分类(category)
一.你用分类都做了哪些事?
1.用分类声明私有方法
2.用分类分解体积庞大的类文件
3.把framework的私有方法公开化
二.分类的特点
1.运行时决议
2.可以为系统类添加分类
三.分类中都可以添加哪些内容?
1.实例方法
2.类方法
3.协议
4.属性
分类添加的方法可以覆盖原类方法(实际上原类的方法还在)
同名分类方法谁能生效取决于编译顺序,最后被编译的分类会优先生效
名字相同的分类会引起编译报错
能否给分类添加“成员变量”?
用@property可以声明属性 但是却不能生成成员变量和setter getter方法,所以如果要访问属性的话,可以使用runtime的关联对象
关联对象的本质
关联对象有AssociationsManager管理并在AssociationsHashMap所有对象的关联内容都在同一个全局容器中
扩展(Extension)
一般用扩展做什么?
1.声明私有属性 2.声明私有方法 3.声明私有成员变量
分类跟扩展的区别?
1.编译时决议,而分类是运行时决议
2.只以声明的形式存在,多数请款下寄生在宿主类的.m文件中
3.不能为系统类添加扩展
代理(delegate)
1.准确的说是一种软件设计模式
2.IOS当中以@protocol形式体现
3.传递方式一对一
4.一般声明为weak以规避循环引用
通知(NSNotification)
1.是使用观察者模式来实现的用于跨层传递消息的机制
2.传递方式是一对多
如何实现通知的机制?
猜想:用观察者模式,也有一个全局表存放着对象,监听回调的;
KVO
1.KVO是OC对观察者设计模式的又一实现
2.苹果使用了ISA混写(isa-swizzling)来实现KVO
KVO原理
当我们注册对象的观察者的时候调用addoberserforkeypath方法,观察者观察对象A的某一个成员变量,系统在运行时为我们创建了一个NSKVONotifying_A这个类并且继承A,之所以这样就是为了在NSKVONotifying_A重写Setter方法负责通知所有的观察对象,这个时候又将对象A的ISA指针指向NSKVONotifying_A这个类,把ISA指向修改就是混写技术的体现;
重写setter方法主要 是 willChangeValueForKey 跟didChangeValueForKey
使用setter方法改变值KVO才会生效
使用setValue:forKey:改变值KVO才会生效
成员变量直接修改需要手动添加willChangeValueForKey 跟didChangeValueForKey kvo才会生效
KVO通过KVC设置的value能否生效?
可以,KVC的setValueforKey调用了setter方法
KVO通过成员变量直接赋值value能否生效?
不可以;因为没有调用willChangeValueForKey 跟didChangeValueForKey
KVC
键值编码
valueforkey系统实现流程
1.首先会通过这个key所访问的实例变量是否有相应的访问器Accessor Method方法,如果Accessor Method方法存在的话会直接调用,然后结束valueforkey的调用流程;
2.如果如果Accessor Method方法不存在,判断实例变量是否存在,如果存在则直接获取实例变量,结束调用流程;
3.如果实例变量不存在,则调用valueforundefinedKey 抛出异常
Accessor Method方法、
getKey key(getter方法)isKey
setValueforKey调用流程
1.首先看有没有setter方法,有的话就直接调用;
2.如果没有setter,则看有没有对应的成员变量,如果有那直接对成员变量赋值;
3.假如说对应的实例变量不存在,那么会调用setterValueforUnderUndefineKey,抛出未定义Key的异常
属性关键字
读写权限:readonly、readwrite(默认)
原子性 :nonatomic、 atomic(默认)、保证赋值获取是线程安全的,使用的话就不能保证线程安全比如数组的操作,赋值是安全,操作数组不能保证安全;
引用计数
retain/strong
assign
1.修改基本数据类型,如int,bool等
2.修饰对象类型时,不改变其引用计数
3.修饰对象时,对象被销毁后,还会指向原对象内存,会产生悬垂指针;
weak
1.不改变被修饰对象的引用计数
2.所指的对象被释放之后会自动置为nil
浅拷贝
浅拷贝就是对内存地址的复制,让目标对象指针和源对象指针指向同一片内存空间;
深拷贝
深拷贝是让目标对象指针和源对象指针指向两片内容相同的内存空间
深拷贝与浅拷贝的区别
1.是否开辟新的内存空间
2.是否影响了引用计数
copy关键字
1.可变对象的copy和mutableCopy都是深拷贝
2.不可变对象的copy是浅拷贝,mutableCopy是深拷贝
3.copy返回的方法都是不可变对象
MRC下如何重写retain修饰变量的setter方法?
-(void)setObj:(id)obj{
if(_obj != obj) {
[_objrelease];
_obj = [objretain];
}
}