OC第八节 内存管理高级
1、MRC情况下,一个alloc对应一个release或autorelease
· 用自定义方法创建对象在最后面加 autorelease ,即alloc创建的对象必须要释放;
· 系统内部的便利构造器后面自动添加有autorelease,所以遍历构造器创建的对象不用加,不然会造成过度释放,产生野指针。
2、容器的内存管理
①. 容器加入一个对象是会被执行一次retain操作,引用计数加 1 ,容器内部的每个对象的应用计数是一样的;
②. 同理,容器移除一个对象时会执行一次release 操作,引用计数减 1;
③. 同样的,在容器释放时,会对容器内所有对象发送一次release消息。
3、属性的setter方法会造成实例变量的内存泄露,可以全部放到dealloc方法重写时执行一次release操作。
4、KVC 键值编码方式,间接访问实例变量,为实例变量赋值和取值
赋值方法 setValue:@"值" forKey:@"键"
取值方法 对象 valueForKey:"键"
通过路径给实例变量赋值的方法 setValue:"值" forKeyPath:"对象.实例变量(即实例变量的路径)"
通过路径获取实例变量的值的方法 对象 valueForKeyPath:"对象.实例变量(即实例变量的路径)"
setvalue: forkey: 方法的执行步骤 (假如key是name)
// 1、去类里面找是否有一个方法叫 setName: ,有的话赋值,没有的话执行第二步
// 2、去类里面找是否有一个实例变量叫 _name ,有的话赋值,没有的话执行第三步
// 3、去类里面找是否有一个实例变量叫 name ,有的话赋值,没有的话执行第四步
// 4、查找当前类是否实现了 setvalue:forUndefindeKey: 方法,如果有,走方法内实现,如果还没有,就会抛出异常,引起崩溃。
valueForKey: 方法的执行步骤 (假如key是name)
// 1、去类里面找是否有一个方法叫 name ,有的话取值,没有的话执行第二步
// 2、去类里面找是否有一个实例变量叫 _name ,有的话取值,没有的话执行第三步
// 3、去类里面找是否有一个实例变量叫 name ,有的话取值,没有的话执行第四步
// 4、查找当前类是否实现了 valueForUndefinedKey: 方法,如果有,走方法内实现,如果还没有,就会抛出异常,引起崩溃。
避免上述两个方法崩溃的方法:- (void)setValue:(id)value forUndefinedKey:(NSString *)key
// 此方法超强
// 1、如果字典中的key多于模型中的实例变量时,我们可以重写此方法,内部空实现,来避免赋值不匹配时出现的崩溃问题。
// 2、可以处理特殊情况,比如字典中的key值是系统保留字,那么这时赋值就会出现问题,我们可以在内部做异常处理。