在XIB里面关于@property,@synthesize,release,dealloc的怪现象

本文深入探讨了Objective-C中IBOutlet的内存管理原理,特别是当IBOutlet与自定义属性名一致时如何导致内存泄漏,并通过实例展示了不同赋值类型的内存管理策略。

在一个XIB中,有一个IBOutlet的UILabel叫 label_ XIB的线已经连好了

IBOutlet UILabel *label_;

如果我定义

@property(nonatomic,assign)UILabel *label_;
@synthesize label_;

那么在dealloc里面加

[label_ release]; 

会造成程序的crash 给出的错误代码是
[CALayer release]: message sent to deallocated instance 0x8f14800(这个数字可以是随便的地址啦)

但是,如果我定义

@property(nonatomic,readonly)UILabel *label_;
@synthesize label_;

在dealloc里面加

[label_ release];

程序就不会crash
进一步,如果我定义

@property(nonatomic,assign)UILabel *label;
@synthesize label = label_;

在dealloc里面加

[label_ release];

程序依然不会crash
自然,即使是把上面的assign换成readonly自然也不会crash
接下来我们继续研究,如果是retain呢
如果我定义这个

@property(nonatomic,retain)UILabel *label_;
@synthesize label_;

那么在dealloc里面

[label_ release];

那么不会crash!
可以想到,如果继续定义

@property(nonatomic,retain)UILabel *label;
@synthesize label = label_;

就更加不会crash了,事实也证明了这一点

看来这玩意儿还是有规律可循的,写了这么多,大概规律也知道了

CocoaTouch 的SDK在将对应的XIB反序列话的时候,会将反序列出类的实例的指针值赋值给你的这个UIView对应的IBOutlet的指针,如果你的这个view 定义了自己存取器方法,而且将存取器的名字替代了IBOutlet的名字(或者说名字取成相同的)(这点很重要,如果不满足这一点的话,则不会出现crash的情况),那么这个赋值操作会调用这个自定义方法,即你的存取器方法定义的引用类型就决定了最终UIView对这个反序列后实例的引用类型, 如果你像上面第一种情况那样子定义assign的话,那么你的UIView对这个UILabel的引用就是assign,所以自然的,你在dealloc 里面就不能调用release。这样想,retain就好理解了,我在想,如果是readonly的话,之所以不会出问题,是因为在这个时候,既然不能用 你自定义的存取器方法对那个类的实例指针进行赋值,那么SDK里面自己的方法还是会按照默认情况下的来,即还是retain,所以在dealloc里面调 用release是不会有什么问题的。

所以简单的原则就是:

如果是IBOutlet的变量,那么定义存取器的时候,假设要做成assign,那么存取器方法的名字一定不要和IBOutlet的名字相同,如果相同了,就不能在dealloc里面release!

第一篇原创的技术文章,写完算是有点感觉了~

 

 

转载于:https://www.cnblogs.com/flyFreeZn/archive/2011/11/29/2267442.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值