oc学习笔记—内存管理

最近感觉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。

●对使用了retain或者copy,mutableCopy,alloc或new方法的任何对象,以及具有retain和copy特性的属性进行释放,需要覆盖dealloc方法,使得对象释放时能释放实例变量。

●如果方法中不需要在用到这个对象,而需要将其返回时,可以给这个对象发送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这些词开头,它会假定方法返回对象的所有者给方法的调用者。

你可能感兴趣的:(ios,osx,内存管理)