最近感觉oc很好玩,所以自己弄来玩玩。
其中部分资源及概念来源于各种书籍教程及互联网。
自学笔记仅记录自己操作及实践的过程并分享。
因本人水平有限,不保证内容的正确性。
如有错误或侵犯,实属意外,请联系我修改或删除。
oc基本内存管理模型有3种
1.自动垃圾收集
oc2.0中有一种称为垃圾收集的内存管理模式。通过垃圾收,系统能够自动检测对象是否有其他对象,当程序执行需要空间时,不再引用的对象会被自动释放。
iOS运行环境并不支持垃圾收集,OSX10.8中已经不再推荐使用,建议使用arc代替。
2.手工引用计数和自动释放池
手工引用计数
创建对象时,发送retain为引用计数加1。[temp retain]
不再需要时,发送release为引用计数减1。[temp release]
当引用计数为0时,通过给对象发送dealloc释放内存。
自动释放池
自动释放池可以帮助追踪需要延迟释放的对象。通过给自动释放池发送drain消息,自动释放池会被清理,对象会被释放。
将一个对象添加到自动释放池[result autorelease]
程序中使用来自Foubdation,UIKit,AppKit框架类时,首先需要创建一个自动释放池。
@autoreleasepool{
statements
}
如果在Xcode中创建新项目时,未启用ARC时,生成的模版main中起始位置就会有这条语句。
当执行到autorelease末尾时,将影响所有发送过autorelease消息并被添加到自动释放池中的对象,会对池中每个对象发送release消息。
自动释放池并不包含实际对象,仅包含对象的引用。对象将在自动释放池被清理时释放。
并不是所有新创建的对象都会被添加到自动释放池中。事实上任何由以alloc,copy,mutableCopy,new为前缀的方法创建的对象都不会被自动释放。
创建结果作为返回对象时可以使用
Fraction *result = [[[Fraction alloc] init] autorelease];
或者
return [result autorelease];
小结
●手工管理内存释放完自身的一些对象后,还需要调用[super release]
●如果需要保持一个对象不被销毁,可以使用 retain。在使用完对象后需要使用release。
●如果方法中不需要在用到这个对象,而需要将其返回时,可以给这个对象发送autorelease消息。autorelease并不会影响到对象的引用计数。
●当应用终止时,内存中所有对象将被释放,不论他们是否在自动释放池中。
●开发Cocoa或者iOS应用时,随着应用的运行,自动释放池会被创建和清空(每次的事件都会发生)。在这种情况下,如果需要对象还能存在,需要使用retain方法。这时只要引用计数大于autorelease的数量就能存在。
3.自动引用计数(ARC)
强变量
当手工内存管理时。
使用f2 = f1;复制对象f1的引用到f2,会导致f2引用丢失,产生内存泄漏。
如果使用ARC,f1和f2都是强变量。这个赋值操作的内存管理其实被编译器帮你做了,如下:
[f1 retain];
[f2 release];
f2 = f1;
因为所有对象变量默认为强变量,所以不需要先声明。然而你仍然可以使用关键字 __strong;
但默认属性却不是strong而是unsafe_unretained(相当于assign)特性。
可以这样将属性声明为strong
@property (strong, nonatomic) NSMutableArray *birdNames;
编译器会保证在事件循环中通过对赋值执行保持操作,强属性能存活,而unsafe_unretained(相当于assign)或weak则不会。
弱变量
当两个对象都持有彼此的强引用时,将会产生循环保持(retain cycle)。如果对象仍然由引用,系统将不能销毁这个对象。
可以通过创建其他类型的对象变量,并允许使用不同类型的引用解决这个问题,即弱引用。
当你声明一个弱变量时,系统会追踪赋值给这个变量的引用。当引用对象被释放时,弱变量会被自动设置为nil。
使用 __weak关键字声明一个弱变量:
__weak UIView *parentView;
或为属性指定weak特性:
@property (weak, nonatomic) UIView *parentView;
●弱变量能够和代理(delegate)很好的协作,创建一个代理的弱变量引用,如果代理对象被销毁,变量就会被清零。
● iOS4 和 Mac OS X v10.6中不知耻弱变量,但可使用unsafe_unretained(或assign)。或将变量声明为 __unsafe_unretained。然而引用对象被销毁时,变量不再被清零。
ARC与未使用ARC编译的代码一起运行,例如需要连接到旧框架,只要非ARC代码与标准Cocoa命名规则一致,都会运行良好。当ARC遇到方法调用时,会检查方法名,如果为new,copy,mutableCopy,alloc或init这些词开头,它会假定方法返回对象的所有者给方法的调用者。