OC中常见基础知识点汇整

  • 1.你如何理解OC这门语言的?谈一下你对OC的理解?
    • OC语言是C语言的一个超集,只是在C语言的基础上加上了面向对象的语言特征,如:继承,封装,多态.
    • 封装:把属性和方法封装成一个类,方便我们使用
    • 多态:不同对象对于同一消息的不同响应,子类可以重写父类的方法,且允许子类类型的指针赋值给父类类型的指针.
    • OC语言的特点:1.支持类别;2.可与C++混编;
    • OC相比C++相比:1.不支持命名空间;2.不支持运算符重载;3.不支持多继承
    • 不支持命名空间:等价于类的前缀;
    • 不支持运算符重载:可以重写运算符的算法,实现对象运算;
    • 不支持多继承:OC中可以使用协议来实现类似多继承的一个功能.
  • 2.C和OC如何混用,C++和OC如何混用:
    • 实现文件的扩展名.m改成.mm即可,但cpp文件必须只能使用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只能写C++的代码.
  • 3.#include与#import的区别?#import与@Class的区别?
    • #include与#import的区别:#include与#import其效果相同,只是后者不会引起重复导入,确保头文件只会导入一次;
    • #import与@class的区别:import是导入头文件,会把头文件的所有信息获取到,这个类有那些变量和方法.而@Class只会告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,完全不知道,所以即使在头文件中使用了@Class,还是需要在.m中导入头文件.
    • 注意:使用@Class是为了防止头文件之间相互导入.
  • 4.你平时是怎么描述NSString类型的?为什么用copy?
    • 一个对象调用copy方法,是深拷贝还是浅拷贝,由copyZone:方法内的逻辑决定的.
    • 假如一个对象的属性是NSString类型,而且使用了retain描述,如果把一个NSMutableString的对象赋值给这个属性.例如:子类的对象可以赋值给父类的指针,属性内部只是retain了一下,还是指向同一个NSMutableString对象,如果将来在赋值完成之后,再次修改NSMutableString的值,那么对象的属性的值也会发生改变,这样肯定是不对的,所以nsstring类型的属性一般使用copy,这样给对象的属性赋值完成之后,对象的属性是重新拷贝了一份,就不用害怕外部再修改,即使修改,也不会影响到属性的值;
    • 总结:NSString使用copy进行修饰是为了防止把NSMutableString赋值给NSString属性,然后修改NSMutableString的值.导致NSString的属性值也发生变化.
    • nonatomic:非原子性,就是多线程访问的时候不加锁,允许多线程同时修改属性的值;
    • atomic:原子性,就是防止在未完成的时候被另外一个线程读取,造成数据错误.
    • 浅拷贝拷贝的是指针,深拷贝拷贝的是对象;
  • 5.assign,retain和copy之间的区别是什么?作用是什么?
    • assign:普通赋值,一般基于数据类型,常见委托设计模式,以此来防止循环引用;
    • retain:保留计数,获得了对象的所有权.引用计数在原有的基础上加1,一般对象类型都是用retain;
    • copy:1>.用来复制对象,一般不可变对象都用copy;2>.还有全局的block变量;3>.还有就是你需要复制一个对象的时候;
      • 一般不可变对象都用copy:对于系统来说,无论是可变对象还是不可变对象,copy和mutableCopy分别返回不可变对象和可变对象;遵循NSCopying协议可以使用copy,遵循mutableCopying协议可以使用mutableCopy;
      • 还有全局的block变量:block需要使用copy修饰,从栈移动到堆上,由我们自己管理内存,ARC下对于block来说,strong和copy的效果是一样的.
  • 6.描述一下viewController的生命周期?
    • 当我们调用UIViewController的view时;
    • 系统首先判断当前的UIViewController是否存在view,如果存在就直接返回view;
    • 如果不存在的话,会调用loadview的方法(调用loadview的时机是:在使用ViewController的view属性,并且view属性没有值的时候调用,创建view并赋值给view属性);
    • 然后判断loadview方法是否是自定义方法;
    • 如果是自定义方法,就执行自定义方法;
    • 如果不是自定义方法,判断当前视图控制器是否有xib,stroyboard;
    • 如果有xib,stroyboard就加载xib,stroyboard;
    • 如果没有就创建一个空白的view;
    • 调用viewDidLoad方法(在viewDidLoad方法执行完毕后调用,只要满足条件,viewDidLoad可有可能多次调用);
    • 最后返回view.
  • 7.你什么时候使用自动释放池?
    • 创建一个分线程的时候,原来不会创建一个自动释放池,现在可以了,不用写也行;
    • 局部大量创建自动释放对象的时候,可以使用嵌套的自动释放池,及时释放局部自动释放对象,防止内存出现高峰.
    • 防止内存出现高峰的方法:
    • 局部对象用完就释放;
    • 全局变量在delloc方法中释放,切要写在[super delloc]的上方;
    • 方法内创建的对象,在方法外使用,使用autorelease延迟释放;
    • 通过静态方法或者字面量方式创建的对象,使用autorelease.
  • 8.你平时开发程序过程中是如何管理内存的?
    • ARC是自动的引用计数,是系统在编译阶段自动的帮助我们在代码中加入release,autorelease等内存管理代码,正因为是在编译阶段加入,所以并不会影响程序的执行效率,反而因为苹果的优化,相比手动内存管理,效率可能会更高,但是使用ARC的时候,有几个需要注意的问题:
      • 自动释放(autorelease)是一种延迟释放机制,在每一个RunLoop结束的时候,自动释放池就会被销毁;
      • 自动释放池本身被销毁的时候,池子里面所有的对象都会做一次release操作;
      • 任何OC对象调用autorelease方法,就会把对象放在离自己最近的自动释放池中;
      • 系统默认创建的自动释放池在方法结束才销毁;
  • 9.ARC存在内存泄露吗?
    • ARC中如果内存管理不当的话,同样会造成内存泄漏,例如:ARC中也会循环引用导致内存泄漏.OC对象与CoreFoundation类之间桥接时,管理不当也会造成内存泄漏.
  • 10.内存中堆和栈的区别?
    • 堆(heap),栈(stack)
    • alloc,new,copy的对象创建在堆上面的,需要我们自己负责管理,若程序员不释放,则内存就会溢出.栈内存一般是由系统自己创建并管理的,例如方法内的指针,形式参数等,系统会把这些变量放到栈中,并在方法结束的时候自动释放掉.
  • 11.strong和weak的区别?
    • strong是强引用,weak是弱引用,强引用指向的对象不会被释放;
    • 强引用指向的对象不会被释放;
    • 弱引用不会对对象的引用计数产生影响;
    • 一个对象没有被强引用会立刻释放,弱引用指向的对象在释放时会自动置空.
  • 12.block的内存问题?使用block需要注意什么?
    • 如果一个block被copy, block会对其中用到的对象retain一次,如果block内部用到了本类的属性和方法,也会self retain一次,而block如果是全局的,这个类本身又copy了这个block,这个时候就形成了循环引用;
    • 解决循环引用:将当前对象赋值给一个局部变量,并且使用__block关键字修饰该局部变量,使用该局部变量访问当前对象的属性和方法;arc中使用__weak代替.
    • block的三种类型:
      • block内部没有使用外部变量,是global类型,分配在全局变量区,是不需要我们自己去管理内存的;
      • block内部使用外部变量,是stack类型,分配在栈上面的,也是不需要我们去管理内存的;
      • 栈上的block copy到堆上,是malloc类型,是需要我们去管理内存的;
  • 13.内存不足,系统会发出警告,此时控制器应该如何处理?当内存不足的时候你该怎么处理?
    • 内存不足的时候,系统会自动调用视图控制器的didReceiveMemoryWarning方法通知控制器内存不足,同时也会发送一个通知.一般需要在此方法中,释放掉自己不需要的对象,如内存中缓存的图片数据等.
  • 14.你是如何理解单元格重用机制的?
    • 重用机制就是一个容器,使用的是字典的存取方式;key就相当于重用标识符,value相当于重用的数组;
    • 当屏幕上单元格滑出屏幕时,系统会把这个单元格添加到重用队列中,等待被重用,当有新单元格从屏幕外滑入屏幕内时,从重用队列中找看有没有可以重用的单元格,如果有,就拿过来用,如果没有就创建一个来使用.
  • 15.ios中数据存储有哪些方式?每种存储方式各有什么特点?都在什么场景下使用?
    • 一共四中方式,属性列表(通过WriteToFile 或者userDefault(偏好设置)存入到Plist文件),对象序列化(归档和解档),SQLite数据库,CoreData;
    • 所有的本地持久化数据存储的本质都是写文件,而且只能存到沙盒中;
    • 沙盒机制:就是苹果的一项安全机制,本质就是系统给每个应用分配了一个文件夹来存储数据,而且每个应用只能访问分配给自己的那个文件夹,其他应用的文件夹是不能访问的;
    • 沙盒中默认有三个文件夹,其中Library文件夹中包括两个子文件,分别是Caches和Preferences文件夹:
      • Documents:存储用户相关的数据,用来存放不会被清理的数据.(用户拍摄的视频,用户创作的图片,用户唱的歌曲,用户收藏的商品),可以在当中添加子文件夹,iTunes备份和恢复的时候,会包括此目录。
      • Library/Caches目录:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除。一般存放体积比较大,不是特别重要的资源。
      • Library/Preferences目录:保存应用的所有偏好设置(偏好设置也就是userDefault),ios的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录
      • tmp:放临时文件,不需要永久存储的,比如下载的时候,需要存储到临时文件中,最终拷贝到Documents或者Library中,iphone重启后会清空tmp目录
    • 属性列表:
      • userDefault(偏好设置)存储7中数据类型:数组,字典,字符串.NSData,NSDate,NSNumber和Boolean;默认会存在沙盒Library 中的Preference文件夹中一个以bundleIdentifier命名的plist(property list 属性列表)文件中.不需要自己再去创建路径
      • 应用于存储少量的数据,比如登录的用户信息,应用程序配置信息等.只有数组,字典,字符串,NSData, Boolean可以通过WriteToFile(图片类型在存储的时候需要先转化为NSData类型)进行存储;依旧是存储在Plist文件;
      • Plist文件中可以存储的7中数据类型:数组,字典,字符串.NSData,NSDate,NSNumber和Boolean.
    • 对象序列化(也叫做归档):
      • 对象序列化最终也是存为属性列表文件,如果程序中,需要存储的时候,直接存储对象比较方便.例如有一个设置类,我们可以把这个设置类的对象直接存储,就没有必要再把里面的每一个属性单独存到文件中.对象序列化是将一个实现了NSCoding协议的对象,通过序列化(NSKeydArchiver)的形式,将对象中的属性抽取出来,转化为二进制,也就是NSData,可是NSData可以通过另外一种方式就是write to file方式或者存储到NSUserdefault中.要想使用对象序列化就必须要实现的两个方法:endcodeWithCoder,initWithCoder.对象序列化的本质就是对象NSData.
      • 对象序列化的本质就是将对象类型转化为二进制数据类型;
      • 对象反序列化的本质就是将二进制数据NSData转化为对象.
    • SQLite(也叫关系性数据库)
      • 适合大量,重复,有规律的数据存储.而且频繁的读取,删除,过滤数据.我们通常使用FMDB第三方
    • CoreData(对象关系映射)
      • 其实就是把对象的属性和表中的字段自动映射,简化程序员的负担,以面向对象的方式操作数据库.
      • CoreData本质还是数据库,只不过使用起来更加面向对象,不关注二维的表结构,而是只需要关注对象,纯面向对象的数据操作方式.我们直接使用数据库的时候,如果向数据库中插入数据,一般是把一个对象的属性和数据库中某个表的字段一一对应,然后把对象的属性存储到具体的表字段中.取一条数据的时候,把表中的一行数据取出,同样需要在封装到对象的属性中,这样的方式有点繁琐,不面向对象.CoreData解决的问题就是不需要这个中间的转化过程,看起来是直接把对象存储进去,并且取出,不关心表的存在,实际内部做好了映射关系.
  • 16.如何优化tableview的使用?
    • 复用单元格;
    • 单元格中的视图尽量都使用不透明的,单元格中尽量少使用动画;
    • 图片加载使用异步加载;
    • 滑动时候不加载图片,停止滑动的时候加载;
    • 单元格内的内容可以在自定义cell类中的drawRect方法内自己绘制;
    • 如非必要,减少reloadData全部Cell.只reloadRowAtIndexPaths
    • 如果cell是动态行高,计算出高度后缓存’
    • cell高度固定的话直接使用cell.rowHeight设置高度;
  • 17.socket和http有什么区别?
    • socket是网络传输层的一种技术,跟http有本质的区别.http是应用层的一个网络协议.使用socket技术理论上来说,按照http的规范,完全可以使用socket来达到发送http请求的目的,只要发送的数据包按照http协议来即可.同时http是用来组织数据的,而socket是用来发送数据的.
    • socket和http的区别:
      • socket是长连接,http是短连接;
      • socket是双向通信,http是单向的,只能客户端向服务器发送数据;
      • socket的数据完全由自己组织,http必须按照http协议来发送.
    • socket使用场景:
      • 客户端频繁请求服务器,如股票应用,需要一直向服务器请求最新的数据,如果使用http,那么:第一,就会频繁链接,造成服务器巨大压力,如果使用socket,一次链接,不会消耗服务器太多资源.第二:频繁发送,返回数据,如果使用http,因为http协议的限制,发送的数据包中包含了很多请求头,请求行等http协议必须带的数据,发送的数据量相比socket大很多,socket只需要请求和返回需要的数据即可,如股票应用中标方,只需要返回股票的最新价格即可,及时性会更高.
      • 客户端和服务器相互发数据,如聊天应用,需要客户端上传聊天内容,同时,别人给你发消息,服务器也能主动把别人发送的消息发送给你.
      • 需要使用socket技术的场景:网络游戏,即使通讯(一般不自己通过sockets来实现,太过复杂,一般使用第三方平台,环信,爱萌),股票软件,自己实现推送机制.
  • 18.什么是http?http协议的特点?http的数据包有那几部分组成?GET和POST请求的区别?你还知道有哪些请求方式?Https是什么?
    • http是超文本传输协议,http是应用层的一个网络协议;
    • 特点:
      • 短连接:是客户端主动发送请求,服务器做出响应,服务器响应之后,链接断开;
      • 单向连接:服务器不能主动向客户端发送数据.
    • HTTP请求报文:
      • 一个HTTP请求报文由请求行,请求头,空行和请求数据4个部分组成;
      • 请求行中规定了请求的方式(get/post),请求的url,请求的http协议版本;
      • 请求头主要是传递一些参数,配置一些设置.常见的有rang头,断点下载使用,cookie头,存储cookie信息,user-agent,表明客户端信息;
      • 请求数据区放置post请求的数据.
    • HTTP响应报文:
      • HTTP响应由三个部分组成,分别是:状态行,响应头,响应正文.
      • 状态行:组成:服务器协议版本,状态码,状态描述.常见的状态码有200(成功),404(url不存在),500(服务器内部错误).一般以2开头的代表成功,以3开头的代表重定向,4开头的代表客户端错误,5开头的代表服务器端错误.
    • 常见的请求方式的是get,post.但是还有OPTIONS,HEAD,PUT,DELETE,TRACE,但是一般很少用.
    • GET请求:参数在地址后拼接,请求数据区没有请求数据,不安全(因为所有的参数都拼接在地址后面),不适合传输大量数据(长度有限制);
    • POST请求:参数在请求数据区放着,相对Get请求更安全,并且数据大小没有限制,一般上传文件使用.
    • 无论是get,post请求.如果url中有特殊字符,如中文,特殊符号等,需要把url编码(字符串调用stringByAddingPercentEncodingWithAllowedCharacters:NSUTF8StringEncoding).
    • https是安全超文本传输协议,它是一个安全通信通道,它基于HTTP开发,用于在客户端计算和服务器之间的交换信息.它使用安全套结字层(SSI)进行信息交换,简单来说它是HTTP的安全版.
  • 19.在项目中你处理http通讯常用那种第三方?
    • 在项目中一般都使用ASIHTTPRequest,因为ASIHTTPRequest不再更新,不支持arc.所以现在都使用AFNetworking.目前在IOS9中发送http请求,需要在info.plist中开启HTTP请求.
    • ASIHTTPRequest,NSURLConnection是对CFNetwork的封装,相对更底层.AFNetworking是对NSURLConnection的封装.ASIHTTPRequest不支持ARC,不再更新,AFNetworking支持ARC,不断在更新.
    • AFNetworking默认支持的响应头格式比较少,不支持text/html,而一般服务器默认返回的类型就是text/html,严格来说,如果服务器返回的是json格式,那么需要把响应头中的content-type改为application/json,但是服务器程序员一般都不改,使用默认值,那么客户端如果使用AFNetworking,就会出现请求失败,所以一般使用AFNetworking.manager.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@“text/html”,nill];需要修改一下这个属性,让他支持这个头.
  • 20.你做项目的时候是如何区分手机网络类型的?
    • 使用苹果官方的reachability这个类,可以区分手机是否联网,并且能区分是手机网络还是wifi网络,至于能不能区分2g,3g,4g,应该是不能的,我项目中没有遇见这种状况.
  • 21.TCP和UDP有什么不同?
    • tcp和udp都是网络传输层的协议**,tcp提供可靠的数据连接,udp提供不可靠的数据连接**,不会对数据包的顺序,是否丢失进行校验,如果丢失也不会重新发送,但是tcp会验证数据包的顺序,丢失还会重新发送,所以是可靠的.但是udp得优点正是因为少了这些校验,及时性更好一些,所以常见的视频聊天,音频聊天都是用的是udp协议,即使丢失一两个包,也无妨,最多声音模糊一下或者画面稍微卡顿.
    • **TCP是面向连接的,一对一的通信,UDP是广播方式,一对多的方式.**我们使用socket的时候,可以选择使用tcp或者udp.
    • CP有三次握手,UDP没有,TCP连接的三次握手:
      • 第一次握手:客户端发送syn包到服务器,并进入SYN_SEND状态,等待服务器确认;
      • 第二次握手:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个syn包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
      • 第三次握手:客户端到服务器的SYN+ACK包,向服务器发送确认包ACK,此时发送完毕,客户端和服务器进入established状态,完成三次握手.完成三次握手后,客户端和服务器之间开始传输数据.
  • 22.网络七层协议,socket是属于那一层的,http是属于那一层的?
    • 应用层,表示层,会话层,传输层,网络层,数据链层,物理层
    • 应用层:
      • 主要功能:用户接口,应用程序;
      • application典型设备:网关;
      • 典型协议,标准应和应用:Telnet FTP,HTTP;
      • 我们做应用层,比如我们做软件,一个视频播放器,这个就是值一个应用层.
    • 表示层:
      • 主要功能:数据的表示,压缩和加密presentation
      • 典型设备:网关
      • 典型协议,标准和应用:ASCLL PLCT TIFF JPED MIDI MOEG
      • 表示层相当于一个东西怎么表示,表示的一些协议,像图片:JEPG声音:MDI视频:MPEG;表示层就是定义这个层的协议的,比如:说某个人说说自己做表示层,可能这个人就是在做MPEG4.
    • 会话层:
      • 主要功能:会话的建立和结束的session;
      • 典型设备:网关;
      • 典型协议,标准和应用:RPC SQL NFS X WINDOWS,ASP;
    • 传输层:
      • 主要功能:端到端控制transport;
      • 典型设备:网关;
      • 典型协议,标准和应用:TCP UDP SPX;
    • 网络层:
      • 主要功能:路由,寻址network;
      • 典型设备:路由器;
      • 典型协议,标准和应用:IP IPX APPETALK ICMP
    • 数据链路层:
      • 主要功能:保证误差错的数据链路data link;
      • 典型设备:交换机,网桥,网卡;
      • 典型协议,标准和应用:802.2,802.3ATM,HDLC,FRAME RELAY;
    • 物理层:
      • 主要功能传输比特流physical;
      • 典型设备:集线路,中继器;
      • 典型协议,标准和应用:V.35,EIA/TIA-232
    • socket,tcp,udp属于传输层,http,ftp是属于应用层.不需要记住每一层的作用,只需要记住名称即可,而且需要知道,下层为上层提供服务.
  • 23.断点续传是如何实现的?
    • 所谓断点续传,也就是再次下载的时候,不是下载的时候,不是下载整个文件内容,而是从已经下载过的数据开始,下载剩下的所有数据.
    • 所以在客户端给服务器发送请求的时候,需要在请求头加上range头,bytes=xx-xxx.xx代表需要下载文件的起始位置,xxx代表结束位置,xxx一般不填,代表从起始位置开始剩下的所有数据.
      • 下载后存放到temp中的文件名=URL进行MD5加密后的结果,既具有唯一性,也不算很长;
      • 使用NSFileHandle向已存在的文件中追加新的数据,需要保证文件一定存在,不存在需要先创建一个空的;
      • 使用NSMutableURLRequest中的setvalue:setValue:向请求头中添加数据;
      • 加入range,下次下载的时候告诉服务器从哪里下载.
  • 24.常用的数据组织格式有哪些?你平时是怎么解析?有哪些数据解析方式?XML和JSON对比,他们有什么优缺点?
    • XML和JSON
      • 平常我们公司一般公司服务器返回的数据格式是json,我一般通过系统的NSJSONSerialization来完成解析.之前系统没有这个类的时候,一般使用第三方库(JSONKit和SBJSON).
      • XML有两种解析方式,Dom(读取全部数据,然后解析)和Sax(边读取,边解析),一般我们都不使用XML这种格式,系统的NSXMLParser可以解析XML,属于Sax方式.
      • Dom方式是先读取文档的整个内容,以节点的方式体现出来;
      • Sax方式是流式解析,一点一点读文档.
    • XML和JSON对比:
      • XML容易读,但是数据量大;
      • JSON数据量小,目前移动端应用普通采用.
  • 25.类别用的多不多?你都是怎么用的?都有什么用?
    • 优点:
      • 不通过继承的方式为原有的类扩充方法;
      • 分散类的实现;
      • 方法的私有化;
    • 缺点:
      • 只能扩充方法,不能扩充变量;
      • 扩充属性时,需要自己实现setter和getter方法;
  • 26.类别和扩展有什么区别?
    • 扩展在写法跟类别一致,只是扩展的括号中没有名字,而类别则有;
    • 扩展可以添加属性,变量,但是没有独立的.m文件;而类别则不能.
  • 27.如何清理图片缓存?
    • 调用SDWebImageCacher的clear(清楚缓存),clean(清除过期缓存)方法.
    • 获取缓存文件的大小:NSInteger Size=[[SDImageCache shareImageCache]getSize];
    • 清理所有的缓存:[[SDImageCache shareImageCache]cleanDisk];
  • 28.SDWebImage的实现原理是什么?
    • 从内存(字典)中找图片(当这个图片在本次使用程序的过程中已经被加载过),找到直接使用;
    • 从沙盒中找(当这个图片在之前使用程序的过程中被加载过),找到使用,缓存到内存中;
    • 从网络上获取,使用,缓存到内存,缓存到沙盒.
  • 29.IOS中你使用过哪些设计模式,你是怎么理解的?
    • 单例模式:
      • 全局只需要一个对象,可以存储到单例类的属性中,这样每个类都可以方便的访问同一份数据.(比如全局的设置类,用户的登录信息);
      • 一个对象的创建比较消耗资源.
    • 代理模式:
      • 解决类和类之间的事件,传递性.把一个类中发生的事件通知到另一个类中,使用代理模式可以降低类和类之间的耦合度;
      • delegate使用assign是防止delegate和self产生循环引用;
    • 观察者(通知,KVO)
      • 代理是一对一,通知是一对多;
      • 代理可以相互传值,通知只能单向传值.发通知的对象给接收通知的对象传值;
      • 通知的效率低于代理(想一想为什么,通知是需要查询所有注册者的信息的,符合接收条件,才调用对象的方法,代理是直接对象调用方法.回顾通知和代理的原理,你就懂了).
      • 代理有有线(有线网络)的,通知是无线(wifi)的.
    • 工厂模式
      • 工厂模式解决的问题是多态,一个类可能有多个子类,具体需要那个子类,工厂根据不同的条件返回不同的子类对象.在IOS中类簇就是工厂模式.(使用类簇的类,NSString,NSNumber,NSArray等).
  • 30.MVC是什么,你对MVC的理解?
    • MVC总体来说解决的问题就是类和类之间的耦合度降低问题,类和类的耦合度降低有利于后期的代码修改,代码扩展,代码维护,代码排错.
    • MVC是一种架构模式,M表示数据模型Model,V表示试图View,C表示控制器Controller.
    • Model负责储存,定义,操作数据;
    • View用来展示数据给用户,和用户进行操作交互;
    • Controller是Model与View的协调者,Controller把Model中的数据拿过来给View用.
    • Controller可以直接与Model和View进行通信,而View不能和Controller直接通信.View和Controller通信需要利用代理协议的方式,当有数据更新时,Model也要与Controller进行通信,这个时候就用notification和KVO,这个方式就像一个广播一样,Model发信号,Controller设置监听器接受信号,当有数据要更新时,就发信号给Controller.Model和View不能直接进行通信,因为这样就违背了MVC的设计思想.
  • 31.你对KVC/KVO的理解?
    • KVC
      • 可以修改只读属性和私有变量的值;
      • Key value Coding是cocoa的一个标准组成部分,他能让我们可以通过name(key)的方法访问property,不必调用明确的property accesser(set/get方法).
      • KVC是一个用于间接访问对象属性的机制(一种使用字符串而不是访问器方法去访问一个对象实例变量的机制).使用该机制不需要调用set或者get方法以及来访问成员变量,它通过setValue:forkey和valueForkey:方法.
      • KVC的机制是啥样的呢?他是以字符串的形式向对象发送消息字符串是要关注属性的关键.是否存在setter,getter方法.如果不存在,他将在内部查找名为_key或key的实例变量,如果没有会调用setValueForUndefindedKey:如果也没有,则会运行报错;注意是如果是基本数据类型,则需要封装一下(NSNumber).
    • KVC的使用环境:
      • 无论是property还是普通的全局属性变量,都可以用KVC.
    • KVC的优缺点:
      • 优点:主要的好处就是减少代码量;没有property的变量也能通过KVC来设置;
      • 缺点:如果key写错时,编译不会报错,运行的时候才会报错.
  • 32.KVO的理解:
    • KVO是一个对象能够观察另外一个对象的属性值,并且能够发现值的变化.KVO更加适合任何类型的对象倾听另外一个任意对象的改变,或者是一个对象与另外一个对象保持同步的一种方法,即当另外一种对象的状态发生改变时,观察对象马上作出反应.他只能用来对属性做出反应,而不会用来对方法或者动作做出反应.
    • KVO的优点:
      • 能够提供一种简单的方法实现两个对象间的同步;
      • 能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象的现实;
      • 能够获得观察的属性的属性的最新值以及先前值;
      • 用key path来观察属性,因此也可以观察嵌套对象(也就是可以观察一个对象内部对象的属性的变化,可以无限嵌套)观察,前提是对象的属性支持KVO);
      • 完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察(不需要像通知一样还需要发送通知,KVO属性的改变,外部可以直接观察).
    • KVO的注意事项:
      • 我们注册KVO的时候,要观察那个属性,在调用注册方法的时候,addObserver:forKey:options:context:forKey处填写的属性是以字符串形式,万一属性名字写错,因为是字符串,编译器也不会出现警告以及检查;
    • KVO的使用:
      • 被观察者发出addObserver:forKey:options:context:方法来添加观察者,然后只要被观察者的keyPath的值变化(注意:单纯改变其值不会调用次方法,只有通过getters和setters来改变值才会触发KVO),就会在观察者里调用方法observerValueForKeyPath:ofObject:change:context:因此观察者需要实现方法observerValueForKeyPath:ofObject:change:context:来对KVO发出的通知作出响应;
      • 这些代码只需要在观察者里进行实现,被观察者不用添加任何代码,所以谁要监听谁注册,然后对响应进行处理即可,使得观察者与被观察者完全解藕,运用很灵活很简单;但是KVO只能检测类中的属性,并且属性名是通过NSSTring来查找,编译器不会帮你查错和补全,纯手敲所以比较容易出错.
  • 33.多线程的实现方式有哪些?并做对比:
    • NSThread:
    • 相当于自己创建一个线程,创建线程的时候,可以把一个方法放到创建的线程中.
      • 优点:NSThread比其他两个轻量级;
      • 缺点:需要自己管理线程的生命周期,线程同步,线程同步时对数据的加锁会有一定的系统开销.
    • NSOperation
    • NSOperation不需要自己创建线程,只关注需要在线程中完成的代码,然后把NSOperation放到NSOperationQueue中即可,NSOperationQueue会把代码放到分线程中执行.
    • NSOperation的作用:配合使用NSOperation和NSOperationQueue也能实现多线程编程.
    • NSOperation和NSOperationQueue实现多线程的具体步骤:
    • 先需要执行的操作封装到一个NSOperation对象中的main方法;
    • 然后将NSOperation对象添加到NSOperationQueue中;
    • 系统会自动将NSOperationQueue中的NSOperation取出来;
    • 将取出的NSOperation封装的操作放到一个新线程中执行;
    • NSOperation的子类:
    • NSOperation是一个抽象类,并不具备操作的能力,必须使用它的子类;
    • 使用NSOperation子类的方式有3种:
      • NSInvocation;在主线程中创建方法,则在主线程中执行;在分线程中创建方法,则在分线程中执行;
      • NSBlockOperation;会自动查找空闲的线程进行使用;
      • 自定义类继承NSOperation,实现内部相应的方法;NSOperation默认是在主线程中开启的.重写main方法,把子类对象放入NSOperationQueue中,就会自动在分线程执行main方法了.
      • 附加:
      • AFNetworking和SDWebimage都是使用来实现异步的;
      • 当多个线程同时修改一个变量的值的时候,需要加锁,防止混乱.
      • 优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上.
    • GCD
    • GCD是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务进行执行的线程池模式的基础上的;
    • GCD的队列是怎么使用的?通过同步或异步的方式把任务提交到队列中;
    • GCD的工作原理:
      • 让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务;
      • 一个任务可以是一个函数或者是一个block.GCD的底层依然是线程实现,不过这样可以让程序员不用关注实现的细节;
      • GCD中必须要使用的是各种队列,我们通过block,把具体的代码放到队列中,队列中的任务排队执行,系统会自动的把队列中的各个任务分配到具体的线程中和cpu中,具体创建多少个线程,分配到哪个cpu上,都是由系统管理.
      • GCD中有三种队列类型:
        • The main queue:系统自带的一个队列,放到这个队列中的代码会被系统分配到主线程中执行.main queue可以调用dispath_main_queue()来获得.因为main queue是与主线程相关的,所以这是一个串行队列,提交至其中的任务顺序执行(一个任务执行完毕以后,在执行下一个任务);
        • Global queues:整个应用程序存在三个全局队列(系统已经创建好,只需要获得即可):高,中(默认),低三个优先级队列.可以调用dispatch_get_global_queue函数传入优先级来访问队列.全局队列是并行队列,可以让多个任务并发(同时)执行(自动开启多个线程r同时执行任务)并发功能只有在异步函数下有效;
        • 用户自己创建队列:dispatch_queue_create创建的队列,可以是串行的,也可以是并行的,因为系统已经给我们提供了并行,串行队列,所以一般情况下我们不再需要再创建自己的队列.用户创建的队列可以有任意多个.
        • 注意:分线程中不能刷新UI,刷新UI只能在主线程.如果每个线程都可以刷新UI,将会很容易造成UI冲突,会出现不同步的情况,所以只有主线程中能刷新UI系统是为了降低编程的复杂度,最大程度的避免冲突.
    • 分线程中回到主线程只要有两种方式:
      • performSeletorOnMainThread;
      • 使用main queue;
    • 分线程在使用的时候,有以下几个需要说明的地方
      • 之前的版本中分线程不会自动创建autorelease pool,所以需要在分线程创建autorelease pool,目前SDK版本已经不需要了;
      • 如果多个线程修改(只是读取变量,不会有问题)同一个资源,需要注意线程同步的问题;
        + timer不能在分线程中直接使用,需要手动开启run loop.
    • 附加:
      • 同步:等待提交的任务执行完毕,才继续执行当前任务;
      • 异步:不等待提交的任务执行完毕,继续执行当前任务;
      • 为什么需要线程?一个线程只能执行一个任务,任务耗时较长,那么后边的任务都处于等待状态,所以需要把耗时较长的任务放入到分线程执行;
      • 多线程是并发执行的;
      • 同步不会产生新的线程;
      • 异步可能会产生新的线程;
      • 同步提交到主线程会造成或死锁现象,在主线程中执行同步的方式提交任务且阻塞主线程.
  • 34.timer的间隔周期准吗?为什么?怎么样实现一个精准的timer?
    • 定时器timer一般都是准确的,但是当主线程有些时候避免会出现堵塞情况,这样就可能导致定时器timer会延迟从而不准确,使用RunLoop就可以准确了.[NSRunLoop currentRunLoop]addTimer:nil forMode:];
  • 35.如何进行网络推送?推送的流程是什么?你的推送是怎么做的?
    • 推送分为本地推送以及网络推送,网络推送APNS分为注册部分以及推送部分,其中注册部分分为:
      • 我们的应用(APP)向我们的系统(指的是手机系统)注册推送;
      • 我们的系统会向用户询问是否允许推送;
      • 用户允许后,我们系统向苹果系统服务器索要device token;
      • 苹果推送服务器会将device token返回我们客户端;
      • 我们应用将device token发送给我们服务器.
    • 推送部分
      • 我们服务器将推送的消息,以及device token发送给苹果推送服务器;
      • 苹果推送服务器会将推送的消息内容发送给我们客户端;
    • 推送注意事项:
      • ios7和ios8推送不同;
      • 如果指定推送声音本地必须有这个文件,如果声音为系统默认声音;
      • 服务器需要配置cer证书,证书生成时,需要CSR证书签名请求;
      • 如果用户选择不允许推送,那么无法进行推送;
      • 推送是免费的;
      • 推送是不可靠的,用户不一定能立即收到该消息;
        + 推送消息大小有限制,长度4M.
  • 36.CALayer和UIView之间的区别与联系?
    • 每一个UIView都包含一个CALayer对象,CALayer中存储的是UIView的展示内容数据,负责绘制.UIView管理CALayer,相当于一个管理者,并具备处理触摸事件的能力(因为uiview继承自uiresponder).
  • 37.核心动画里面有哪些常用的动画类?
    • 常用的动画类:CABasicAnimation基础动画,CAKeyframeAnimation关键帧动画,CAAnimationGroup动画组,CATransition转场动画.
  • 38.常用的手势有哪些?如何自定义手势?
    • 系统提供了七种手势帮我们进行手势的识别开发:点击UITapGesture,滑动UIPanGestureRecognizer,轻扫UISwipeGestureRecognizer,旋转UIRotationGestureRecognizer,缩放UIPinchGestureRecognizer,长按UILocalizedIndexedCollation,屏幕边缘滑动UIScreenEdgePanGestureRecognizer;
  • 39.地图定位偏移你该怎么办?(火星坐标)
    • 火星坐标系统是一种国家保密处理,其实就是对真实坐标系系统进行人为的加偏处理,按照特殊的算法,将真实的坐标加密成虚假的坐标,而这个加偏并不是线性的加偏,所以各地的偏移情况都会有所不同.而加密后的坐标也常被人称为火星坐标系统.
    • 解决方式一:在GPS软件中设置一个使用同样算法的加偏移功能,即:GPS先从卫星上得到真实坐标,然后经过加偏移程序转换成火星坐标,由于是同一个算法,所以经过软件加偏移的坐标能跟同样加了偏移的地图吻合,一般不使用,太麻烦,也不知道转换算法,这种方式是专业制作地图的公司可能会使用;
    • 我们使用第三方t地图的时候,第三方地图肯定已经处理过,直接用系统的CALLocationManager获得坐标是真实没有处理的,但是第三方地图中,如百度地图,传入的坐标要经过处理,所以最好的方式就是定位坐标的代码,和显示地图的代码使用同一个平台的代码.例如:如果你使用百度地图,就不要使用CALLocationManager来获取坐标,再传入百度地图,这样地图就会出现偏移.应该使用BMKLocationService来获得坐标,再传入百度地图,这样才能显示正确.
  • 40.OC的消息机制你知道不知道?
    • runtime相当于OC转换成C的代码,可以实现许多OC实现不了的功能或者比较麻烦的功能.例如:为类别添加属性;
    • 只需要回答,系统内部是靠objc_msgSend来现实方法调用的所有的oc方法的调用都会编译为objc_msgSend方法.
  • 41.OC的事件响应者链
    • 响应者链表示一系列的响应者对象.事件被交由第一响应者对象处理,如果第一响应者不处理,事件被沿着响应者链向上传递,交给下一个响应者.一般来说,第一响应者是个视图对象或者其子类对象,当其被触摸后事件被交由其他处理,如果不处理,事件就会被传递给它的视图控制器对象(如果不存在).如果是他的父视图(superview)对象(如果存在),以此类推,直到顶层视图.接下来会沿着顶层(top View)到窗口(UIWindow对象)再到程序(UIApplication对象).如果整个过程都没有响应这个事件,该事件就被丢弃.一般情况下,在响应者链中只要由对象处理事件,事件就停止传递.但有时候可以在试图的响应方法中根据一些判断条件来决定是否需要继续传递事件.
    • 常用UIView的下一个响应者是它的superview,但是当UIView是UIViewController的根试图的时候,它的下一个响应者就是UIViewController.UIViewController的下一个响应者是其根视图的superview.依次类推,直到UIWindow.UIWindow不处理UIApplication传递给APPDelegate,也不处理,事件就抛弃不再处理,只要有一个响应者处理事件,事件就不再传递.
  • 42.常用的数据机构都是有哪些?
    • 数据结构是计算机存储,组织数据的方式.如数组,字典都是一种数据结构,他们的组织方式和原理就不一样.下面说的这些都是比较理论的,在不同的语言中,可能有不同的实现方式,例如在IOS中NSDictionary就是类似hash表的一种结构.
      • 栈:先进后出,相当于一个没有盖子的杯子;
      • .队列:先进先出,相当于一个水管;
      • 二叉搜索树;
      • 散列表(hash表);
      • 检索树(Trie);
      • 优先队列;
      • 线段树和树状数组;
      • 后缀树与后缀数组;
      • 并查表;
      • 邻接表和边表;
      • 数据元素相互之间的关系成为结构.有四类基本结构:集合(元素放在一起相互之间没有任何关系,例:数组);线性结构(元素之间存在一一对应的关系,例如:链表,栈,队列);树形结构(元素之间存在一对多的关系,例如:二叉树);图状结构(元素之间存在多对多的关系,例如:表,导航,z游戏中的自动寻路);
        • 集合结构:除了同属于一种类型外,别无其他关系;
        • 线性结构:元素之间存在一对一关系常见类型有:数组,链表,队列,栈,他们之间在操作上有所区别.例如:链表可在任意位置插入或删除元素,而队列在队尾插入元素,队头删除元素,栈只能在栈顶进行插入,删除操作;
        • 树形结构:元素之间存在一对多关系,常见类型有:树(有许多特例:二叉树,平衡二叉树,查找树等);
        • 图形结构:元素之间存在多对多关系,图形结构中每个结点的前驱结点数和后续结点数可以任意多个.
  • 43.如何将产品进行多语言发布,做国际化开发?
    • 下面是步骤,可以简洁的回答为,把程序内需要用的字符串,写为多个语言版本,程序内通过NSLocalizedString宏定义来读取,系统会根据本机语言,来读取对应的语言文本.
      • 新建String File文件,命名为Localizable.strings,往里面添加你想要的语言支持;
      • 在不同的语言的Localizable.strings文件中添加对应的文本.
      • XIB国际化.在需要国际化的XIB文件上添加get Info添加多语言版本,修改个语言版本相应的界面文字及图片.
      • 程序名称国际化.新建一个sytring文件,然后国际化它,get info…
  • 44.OC的RunLoop的应用
    • 目的:是让你的线程在有工作的时候忙于工作,而没有工作的时候出于休眠状态.
    • 应用:
      • 提高NSTimer的优先级;
      • 降低加载图片的优先级,滚动tableview不加载图片;
  • 45.iOS系统的版本比较多,你是如何适配的?
    • 一般可以通过系统的宏定义或者UIDevice中的systemVersion来判断系统的版本.如果低版本和高版本中要实现同一个功能,api或者处理流程不一样,会使用条件编译来处理,把低版本,高版本的代码都写出来,根据不同的系统版本,选择性的来编译不同的代码.
  • 46.iOS上应用是如何兼容32位系统和64位系统?
    • 在XCode中打开工程,在Project Setting里面,把最小应用使用的SDK5.1.1或者更高的版本,把build setting中的Architectures参数设置成"Standard Architectures".这样你的应用就支持了64位的CPU,再次修复编译器的错误或警告.
    • 注意:修改之后,如果你的程序内使用是int float,那么可能会存在隐患.因为在64位的系统上,所占用的字节数可能跟32位系统上的不一致,最好使用NSInteger来代替int,CGFloat代替float,这样系统可以自动替换的类型.
    • 应用在兼容64位系统后,内存的占用肯定会变多一点(因为安装包中h包含了32位和64位的两套指令),不过性能也有相应的提升.
  • 47.如何打包静态库?
    • 新建一个Framework&Library的项目,编译的时候,会将项目中的代码文件打包成一个.a的静态库文件.
    • 编译的h时候分为device(arm版本)版本和模拟器版本.
  • 48.如果使用svn静态库如何提交?
    • 直接提交不上去,一般通过命令行收到提交上去,一般svn工具是默认无法提交.a文件的.
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值