面试宝典1之基础篇
1、category 和 extension 的区别?

1> 分类有名字,类扩展没有名字。
2> 分类只能扩展方法(属性仅仅是声明,并没真正实现)。
3> 类扩展可以扩展属性、成员变量和方法。

2、define 和 const 常量有什么区别?

1> define 在预处理阶段进行替换,const 常量在编译阶段使用
2> 宏不做类型检查,仅仅进行替换,const 常量有数据类型,会执行类型检查 define 不能调试,const 常量可以调试。
3> define 定义的常量在替换后运行过程中会不断地占用内存,而 const 定义的常量 存储在数据段只有一份 copy,效率更高
4> define 可以定义一些简单的函数,const 不可以

3、 堆和栈的区别? 
1、从管理方式来讲 :
a、对于栈来讲,是由编译器自动管理,无需我们手工控制;
b、对于堆来说,释放工作由程序员控制,容易产生内存泄露,
2、从申请大小大小方面讲:
栈空间比较小
堆控件比较大。
3、从数据存储方面来讲:
栈空间中一般存储基本类型,对象的地址 堆空间一般存放对象本身。

4> ARC下还会存在内存泄露吗?

答:会。
1、循环引用会导致内存泄露
2、Objective-C 对象与 CoreFoundation 对象进行桥接的时候如果管理不当也会造成内存泄露。

5、weak与assign的不同点?

1、使用weak修饰属性,当该属性所指的对象被释放的时候,系统会向weak修饰的属性对象指针指向nil(在 OC 给 nil 发消息是不会有什么问题的)

2、使用assign修饰属性,当该属性所指的对象被释放的时候,属性对象指针还指向原来的对象,由于对象已经被销毁,这时候就产生了野指针,如果这时候在给此对象发送消息,很容易造成程序崩溃。

3、assigin 可以用于修饰非 OC 对象,而 weak 必须用于 OC 对象。

6、@property的本质是什么?

答:@property 其实就是在编译阶段由编译器自动帮我们生成 ivar 成员变量,getter 方 法,setter 方法

7、@property后面有哪些修饰符?

1、nonatomic/atomic
如果不写系统默认就是atomic,在iOS开发中尽量使用nonatomic,有助于提高性能。

2、readonly/readwrite
如果不写系统默认readwrite,可读可写。
Readonly:只读。系统默认只会生成getter方法。

3、strong/weak/copy
strong(强引用)会使该属性所指的对象的引用计数器 +1。
Weak(弱引用)不会对引用计数器+1(block发生循环引用时会使用weak来弱化self指针)。
Copy一般修饰NSString,block等。

4、assign
修饰基本类型,也可以修饰对象(不建议这么做)。

8、这个写法会出什么问题: @property (copy, nonatomic) NSMutableArray *array;?

答:copy 策略拷贝出来的是一个不可变对象,然而却把它当成可变对象使用,很容 易造成程序奔溃 。

9、Foundation 对象与 Core Foundation 对象有什么区别 ?

1、Foundation 框架是使用 OC 实现的,Core Foundation 是使用 C 实现的 。

2、Foundation 对象 和 Core Foundation 对象间的转换(俗称桥接)

a、__bridge:用于Foundation对象 转成 Core Foundation对象

b、__bridge_retained:用于Foundation对象 转成 Core Foundation对象

c、__bridge_transfer:Core Foundation对象 转成 Foundation对象

10、 什么是浅拷贝?什么是深拷贝?

1> 在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存。

2> 深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存。

11、 如何让自定义类可以使用copy修饰符?

实现协议,重写copyWithZone方法。

12、IBOutlet 连出来的视图属性为什么可以被设 置成 weak?

答:因为父控件的 subViews 数组已经对它有一个强引用。

13、沙盒目录结构是怎样的?各自用于那些场景?

1> Application:存放程序源文件,上架前经过数字签名,上架后不可修改.

2> Documents:常用目录,iCloud 备份目录,存放数据

3> Library:

a、Caches:存放体积大又不需要备份的数据
b、Preference:设置目录,iCloud 会备份设置信息

4> tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能。

14、全局变量和静态变量有什么相同点?又有什么不同点?

相同点:
1> 存储地址
  两者都是存储在静态存储区,非堆栈上,它们与局部变量的存储分开。
2> 生命周期
  两者都是在程序编译或加载时由系统自动分配的,程序结束时消亡。

不同点:
1> 修饰符:
全局变量在声明源文件之外使用,需要extern引用一下。
  静态变量使用static来修饰。
2> 外部可访问性                                
  全局变量在整个程序的任何地方均可访问,而静态变量相当于面向对象中的私有变量,他的可访问性只限定于声明它的那个源文件,即作用于仅局限于本文件中。

15、描述下 SDWebImage 里面给 UIImageView 加载图片的逻辑 ?

1> SDWebImage中为UIImageView 提供了一个分类 UIImageView+WebCache.h, 这个分类中有一个最常用的接口 sd_setImageWithURL:placeholderImage:,会在真实图片出现前会先显示占位图片,当真实图片被加载出来后在替换占位图片。

2> 加载图片的过程大致如下:

a、首先会在 SDWebImageCache 中寻找图片是否有对应的缓存,它会以 url 作为数据的索引先在内存中寻找是否有对应的缓存。

b、如果缓存未找到就会利用通过 MD5 处理过的 key 来继续在磁盘中查询对应的数据,如果找到了, 就会把磁盘中的数据加载到内存中,并将图片显示出来。
c、如果在内存和磁盘缓存中都没有找到,就会向远程服务器发送请求,开始下载图片,下载后的图片会加入缓存中,并写入磁盘中。整个获取图片的过程都是在子线程中执行,获取到图片后回到主线程将图片显示出来。

16、如何渲染 UILabel 的文字?

答:
1> 通过 NSAttributedString/NSMutableAttributedString(富文本)来实现。
2> 利用第三方框架YYText来实现,链接: https://github.com/ibireme/YYText

17、Objective-C如何对内存管理的,说说你的看法和解决方法?

1> 每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁
2> 通过retain可以让对象的计数器+1、release可以让对象的计数器-1
3> 还可以通过autorelease pool管理内存
4> 如果用ARC,编译器会自动生成管理内存的代码

18、什么是响应者链?

答:响应者链:
1、UIResponder有一个nextResponder属性,通过该属性可以组成一个响应者链,事件或消息在其路径上进行传递。
2、如果UIResponder没有处理传给它的事件,会将未处理的消息转发给自己的nextResponder。

19、数据持久化的方案有哪几种?请简单描述一下?

1> 属性列表(plist文件)
2> Preference(NSUserDefaults)
3> 键值归档(NSKeyedArchiver、NSCoding)
4> SQLite数据库
5> Core Data

20、谓词有哪些用处?

答:谓词:可以以一定条件来过滤数组、字典等集合数据,也能用在Core Data的数据查询中。

21、ViewController的didReceiveMemoryWarning是在什么时候调用的?默认的操作是什么?

1> 当应用程序接收到系统的内容警告时,就有可能调用控制器的didReceiveMemoryWarning方法。
2> 它的默认做法是:
当控制器的view不在窗口上显示时,就会直接销毁,并且调用viewDidUnload方法。

22、ViewController 的loadView、viewDidLoad、viewDidUnload分别是什么时候调用的,在自定义ViewCointroller时在这几个函数中应该做什么工作?

1、loadView
当第一次使用控制器的view时,会调用loadView方法创建view
一般在这里自定义view。

2、viewDidLoad
当控制器的view创建完毕时会调用,也就是在loadView后调用
一般在这里添加子控件、初始化数据

3、viewDidUnload
当控制器的view因为内存警告被销毁时调用
一般在这里回收跟界面相关的资源(界面都会销毁了,跟界面相关的资源肯定不要了)。

23、static的作用?

1> static修饰的函数是一个内部函数,只能在本文件中调用,其他文件不能调用
2> static修饰的全部变量是一个内部变量,只能在本文件中使用,其他文件不能使用
3> static修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存

24、对象是什么时候被释放的?

答:每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁。

25、请说一下CAAnimation的层级结构?

26、堆和栈的区别?

答:
1> 管理方式:

a、对于栈来讲,是由编译器自动管理,无需我们手工控制;

b、对于堆来说,释放工作由程序员控制,容易产生memory leak。

2> 申请大小:

a、栈是向低地址扩展的数据结构,是一块连续的内存的区域,栈顶的地址和栈的最大容量是系统预先规定好的,能从栈获得的空间较小。

b、堆是向高地址扩展的数据结构,是不连续的内存区域,因为系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存,因此堆获得的空间比较灵活,也比较大。

3> 碎片问题:

a、对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。
b、对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出

4> 分配方式:

a、堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配

b、栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

5> 分配效率:

a、栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

27、UIImage有哪几种加载方式?

1> 二进制 :imageWithData

2> Bundle :imageWithName

3> 本地路径 :imageWithContentOfFile