objective-C基础教程(第2版)-第九章笔记

OC内存管理

cocoa采用引用计数进行内存管理,即当访问一个对象是该对象的保留计数器值+1,当结束访问后对象的保留计数器-1

当使用alloc,new方法或通过copy消息创建一个对象是,对象的保留计数器值设置为1,改变这个值可以通过发送retain消息+1, release消息-1
当一个对象的保留计数器归0即将销毁时,oc会自动向对象发送一条关于dealloc的消息

[obj retain]; // 保留数 + 1
[obj release]; // 保留数 - 1
[obj retainCount]; // 获取保留数

OC的自动释放池
NSObject提供了一个叫做autorelease的方法将预先设定一条会在某个时间发送release消息,其返回值是接收这条消息的对象,当对该对象发送autorelease消息时实际上是将该对象添加到自动释放池中,当自动释放池被销毁时将向该池中的所有对象发送release消息
oc中可通过@autoreleasepool(推荐)或NSAutoreleasePool对象创建一个自动释放池

// 花括号中的代码将会被放入新池子中;推荐关键字方法,比对象更
关键字方法 @autoreleasepool{}
// 创建和释放该对象之间的代码会使用新池子
对象NSAutoreleasePool

自动释放池以栈的形式实现,新创建的自动释放池会被添加到栈顶,接收autorelease消息的对象将被放入栈顶的自动释放池中


ARC自动引用计数,ARC会最终你的对象并在编译器中帮你插入retain和release,ARC不是垃圾回收器
objective-C基础教程(第2版)-第九章笔记
在代码中使用ARC需满足以下三个条件

  • 能明确哪些对象需要进行内存管理
  如C型数组不是可保留对象使用无法使用ARC特性
  • 能表明如何去管理对象
必须能对某个对象的保留计数器进行+1或-1的操作,也就是说NSObject类的子类都能进行内存管理
  • 有可行的办法传递对象所有权
传递对象是,你的程序必须能够在调用者和接收者之间传递所有权

当用指针指向某个对象时,你管理它的内存就拥有该对象的强引用,如果没有管理则拥有的是弱引用

当出现循环引用时,如下图,持有一个A对象,A对象内部持有一个B对象,同时B对象又拥有指向A的引用,则当外部不再指向A对象时,会导致A,B对象由于循环引用的问题没有被释放,因此需要弱引用来破解
objective-C基础教程(第2版)-第九章笔记
将B指向A的引用改为弱引用,因为是弱引用所以保留计数器的值不会增加,当外部释放A时提示也会释放B
objective-C基础教程(第2版)-第九章笔记

但是当三个对象相互引用如下图时
objective-C基础教程(第2版)-第九章笔记
当A释放了B时,C仍将拥有B的弱引用,直接使用它会导致问题,其指向的地方已经没有有效值了。这种情况的解决方案为让对象自己去清空弱引用的对象,这种特殊的弱引用被称为归零弱引用,当指向的对象释放后,这些若引用会被设为零(nil)
归零弱引用的使用

声明变量是使用__weak关键字或对属性使用weak特性@property(weak) 
同样强引用可以用__strong或strong特性

ARC和垃圾回收机制无法一同使用

异常NSException
OC中的异常处理感觉没太大用处,因为异常处理无法捕捉内存泄露引起的崩溃,而这也是iOS应用中最常重新的崩溃,所以就大致记录下
objective-C基础教程(第2版)-第九章笔记
抛出异常可以用@throw 异常对象或[异常对象 raise],但两者不能同时使用,raise只对NSException对象有效,而@throw可以用在其他对象上。
@catch异常代理代码中可以直接使用@throw重复抛出异常而无需指定异常对象

@try建立一次不会产生消耗单捕捉异常会消耗大量的资源并影响程序运行的速度,另外异常也需要内存管理

上一篇:Objective-C 对象释放方法调用过程


下一篇:Objective-C 30分钟入门教程