zoukankan      html  css  js  c++  java
  • 在XIB里面关于@property,@synthesize,release,dealloc的怪现象

    在一个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!

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

  • 相关阅读:
    *关于如何获取指定表的指定字段的数据类型的方法
    *检查表是否存在
    *用Sql添加删除字段,判断字段是否存在的方法
    *MSSQL三个关键系统表
    *系统表的应用
    VC++ ADO编程入门简介
    int i=0; i=i++ System.out.Println(i)
    Microsoft Visual C++ 6.0 关联源代码
    VC ADO接口详解
    程序员每年该做的事
  • 原文地址:https://www.cnblogs.com/flyFreeZn/p/2267442.html
Copyright © 2011-2022 走看看