内存管理

手工管理内存计数

概念

当创建对象时,初始的引用计数为1。每当创建对象的引用时对象引用计数应+1。可以给对象发送retain消息。

[myFraction retain];

当不需要对象时,通过发送release消息,为引用计数-1。

[myFraction release];

当引用计数为0时,系统就知道这个对象不再需要使用了,所以可以释放它的内存。
通过给对象发送dealloc(NSObject)消息释放它的内存。
为了能够释放由对象创建或保持的实例变量或者其他对象,需要覆盖dealloc方法。
当使用手工内存管理引用计数时应注意Foundation框架中的一些方法可能会增加对象的引用计数(UIView的addSubView等)。有些方法会减少对象到引用计数(removeFromSuperView:)。
当对象被销毁后,对象的引用失效,这样的指针称为悬挂指针。给悬挂指针发送消息会导致程序崩溃。对对象的过度release操作会造成程序的崩溃。

对象引用和自动释放池

开发过程中经常会遇到如下问题:创建一个对象,然后将它作为方法调用的结果返回。这样尽管方法不再使用它,但是却不能释放它。NSAutoreleasePool类可以解决这类问题。
-将对象加入自动释放池

[result autorelease];

-创建自动释放池

NSAutoreleasePool pool = [[NSAutoreleasePool alloc]init];

-清理自动释放池
清理自动释放池会对池内的对象进行release操作。

[pool drain];

注意[1]:使用来自Foundation,UIKit,AppKit等框架中的类时,需要先创建一个自动释放池,因为来自这些框架的类会创建并返回自动释放对象。
注意[2]:并不是所有新创建的对象都会添加到自动释放池中,凡是以alloc, new, copy, mutableCopy为前缀的方法创建的对象都不会被自动释放。
注意[3]:方法A中创建了一个对象,并将该对象作为方法的返回值返回给调用的方法,return之前不能对对象进行release操作,这样会使得返回的对象指针为悬挂指针。正确的处理方式为return [result autorelease];

事件循环和内存分配

事件是伴随着某些行为而发生的。ios应用和Cocoa应用运行在事件循环中。为了处理一个新的事件,系统会自动创建一个内存释放池,可能会调用到应用中的一些方法来处理这个事件。当事件处理结束,系统开始等待下一个事件,然后在此之前,系统会清理自动释放池。意味着:事件处理工程中创建的自动释放池被释放,池内的对象将销毁。除非对象使用retain操作,才能从清空到释放池中幸存。

属性修饰符

retain:表示设置值之前先会释放旧值。

//属性声明
@property (nonatomic, retain)NSMutableArray *data;

// 属性实例化
//在事件结束时,自动释放池释放data被销毁
data = [NSMutableArray array];
data = [[NSMutableArray array] retain]; //保持
data = [[NSMutableArray alloc] init]; //保持
self.data = [NSMutableArray array];//保持

//销毁
-(void)dealloc{
    [data release];
    [super release];
}

属性修饰符翻译

self.property = newValue;
//assige
property = newValue;
//retain
if(property !=newValue){
    [property release];
    property = [newValue retain];
}
//copy
if(property!=newValue){
    [property release];
    [property copy];
}

自动引用计数

使用自动引用计数,系统会检测何时需要保持对象,何时需要自动释放对象。

强变量

通常,所有对象的指针变量都是强变量。
强变量赋值时,如:f1 = f2;会先对f2进行retain操作,再对f1进行release操作。
所有对象默认都是强变量,不需要声明,可使用__strong 声明
属性的默认值不是strong,是unsafe_unretained(assign)
声明强变量

@property (strong, nonatomic)NSMutableArray *array;

编译器会保证事件循环中,通过对赋值保持操作,将强变量保存下来。

弱变量

当两个对象都持有彼此的强引用时,将产生循环保持,如果对象仍然有引用,系统将不能销毁这个对象,如果两个对象都强引用到彼此,这样就不可以销毁。
当声明一个弱引用时,系统会追踪赋值给这个变量的引用。当引用对象释放时,弱变量会自动设置为nil,给nil对象发送消息不会有任何反应,所有不会导致程序崩溃。
可以使用__weak声明一个弱变量。或者为属性指定为弱引用

@property (nonatomic, weak)UIView *view;

注意:弱引用变量可以和代理进行很好的协作,创建一个代理的弱引用变量,如果代理对象被销毁,变量就会被清零。
ios4和MacOSV10.6中不支持弱变量。使用unsafe_unretained(assign)或(__unsafe_unretained)。然而当对象被销毁时,变量不再被清理。

autoreleasepool块

@autoreleasepool{}这个语句围住的范围定义了自动释放池的上下文。
如果程序中大量使用了临时变量,可以添加多个自动释放池。如:

for(int i=0; i<n; i++){
    @autoreleasepool{
        //与临时变量打交道。
    }
}

tip:在ios应用和Cocoa应用的事件循环中。事件结束时释放自动释放池在ARC模式下系统已经帮你做好了,不需要自己做任何操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值