四、扩展
1、一般用扩展做什么?
1)、声明私有属性
2)、声明私有方法
3)、声明私有成员变量
2、扩展的特点(与类别的区别)
1)、编译时决议
2)、只以声明的形式存在,多数情况下寄生于宿主类的.m文件中
3)、不能为系统类添加扩展
五、代理
一般针对初级工程师考察代理,对中级及以上工程师考察的比较少。
1、代理的理解
1)、准确的说是一种软件设计模式
2)、iOS中以@protocol形式体现
3)、传递方式一对一(与通知的区别)
2、代理的工作流程
六、通知
1、通知的理解
1)、通知是使用观察者模式来实现的用于跨层传递消息的机制
2)、传递方式为一对多
2、通知和代理的区别
1)、通知是观察者模式实现的,代理是代理模式实现的
2)、通知传递方式一对多,代理是一对一
3)、如何实现通知
NS开头的系统类苹果没有公布源码,根据观察者模式大致说一下实现过程就好。
七、KVO
1、什么是KVO
1)、KVO是Objective-C对观察者模式的又一实现
2)、Apple使用了isa混写(isa-swizzling)来实现KVO
2、KVO的实现机制是怎样的
3、KVO对setter方法的实现
4、通过KVC设置属性值能否使KVO生效?为什么?
能。这需要了解KVC的原理,因为KVC过程中调用了属性的setter方法。
5、通过成员变量直接赋值能否使KVO生效?
不能。此时可以在成员变量赋值语句的前后手动调用willChangeValueForKey和didChangeValueForKey方法来使KVO生效。
八、KVC
1、什么是KVC
是键值编码技术,通过key设置/获取对象中同名的属性的值。主要有两个函数:
-(id)valueForKey:(NSString *)key
-(void)setValue:(id)value forKey:(NSString *)key
2、KVC是否破坏面向对象编程思想
破坏。因为一个私有属性通过KVC也能获取/设置其值。
3、valueForKey的系统实现
Accessor Method方法用来判断类中是否有相应的访问器,如果类中实现了getKey、key、isKey方法则系统认为类中存在相应的访问器方法,则调用访问器方法实现相关操作。
如果访问器方法不存在则判断同名/相似名称的实例变量是否存在,如果存在则操作相应的实例变量。实例变量的判断规则:存在_key、_isKey、key、isKey实例变量则认为存在同名/相似名称的实例变量。
4、setValue:forKey:的系统实现流程
九、属性关键字
1、属性关键字分为几类
1)、读写权限:readonly、readwrite(默认)
2)、原子性:atomic(默认)、nonatomic
3)、引用计数:retain/strong、assign/unsafe_unretained、weak、copy
unsafe_unretained在MRC中用的比较多,在ARC中基本上已经退出舞台了。
2、atomic能保证线程安全吗
只能保证对所修饰对象的设置和获取是安全的,其他的不保证。比如修饰数组时,对数组的赋值是安全的,但是向数组中添加元素和删除元素则不保证安全。
3、assign的特点
1)、修饰基本数据类型,如int、BOOL等
2)、修饰对象类型时,不改变其引用计数
3)、会产生野指针
4、weak的特点
1)、不改变被修饰对象的引用计数
2)、所指对象在被释放之后会自动置为nil
5、assign和weak的区别是什么?
1)、weak修饰对象,assign既可以修饰基本类型,也可以修饰对象,但一般不修饰对象。
2)、weak修饰对象被释放后置为nil,assign修饰的对象释放之后仍指向原地址
6、浅拷贝、深拷贝,及两者区别
1)、浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。
2)、深拷贝让目标对象指针和源对象指针指向两片内容相同的内存空间。
3)、区别:是否开辟了新的内存空间、是否影响了引用计数。
7、可变对象和不可变对象copy操作的区别
8、MRC下如何重写retain修饰的setter方法?
为什么要判断新老对象是否相等呢?主要是因为如果两者是同一对象,则release之后对象就可能被内存回收了,再retain就会出错,所以要判断。其次这样也可以防止对属性赋值同一个对象。