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!

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

  • 相关阅读:
    VTemplate模板引擎的使用--入门篇
    VTemplate模板引擎的使用--进阶篇
    装载当前页面的模板文档
    学习平台判断是否是手机端
    畜禽免疫系统使用LODOP打印
    关于.NET编译的目标平台(AnyCPU,x86,x64)(转)
    ConcurrentHashMap原理分析(1.7与1.8)
    Synchronized方法锁、对象锁、类锁区别
    谈谈线上CPU100%排查套路
    java-虚拟机-索引
  • 原文地址:https://www.cnblogs.com/flyFreeZn/p/2267442.html
Copyright © 2011-2022 走看看