使用ARC时,我是否在dealloc中将属性设置为nil?

emf*_*rry 123 objective-c ios automatic-ref-counting

我正在尝试学习iOS 5中的自动引用计数.现在这个问题的第一部分应该很简单:

  1. 它是正确的,我使用ARC时需要写在我的dealloc明确释放属性声明?换句话说,这是真的,以下就不是需要一个明确的dealloc的?

    @interface MyClass : NSObject
    @property (strong, nonatomic) NSObject* myProperty;
    @end
    
    @implementation MyClass
    @synthesize myProperty;
    @end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我的下一个也是更重要的问题来自" 转换为ARC发行说明"文档中的一行:

    您不必(实际上不能)释放实例变量,但您可能需要在系统类和其他未使用ARC编译的代码上调用[self setDelegate:nil].

    这引出了一个问题:我怎么知道哪些系统类没有用ARC编译?我什么时候应该创建自己的dealloc并明确地将强保留属性设置为nil?我应该假设属性中使用的所有NS和UI框架类都需要显式的deallocs吗?

在使用手动参考跟踪时,有关SO和其他地方有关释放财产支持ivar的做法的大量信息,但在使用ARC时相对较少.

Lil*_*ard 197

简短回答:不,你不必dealloc在ARC下输掉属性.

答案很长:dealloc即使在手动内存管理中,也不应该忽略属性.

在MRR中,您应该释放您的ivars.Nilling out属性意味着调用setter,它可以调用它不应该触及的代码dealloc(例如,如果你的类或子类覆盖setter).同样,它可能会触发KVO通知.释放ivar反而避免了这些不良行为.

在ARC中,系统会自动为您释放任何ivars,因此,如果这就是您所做的一切,您甚至不必实施dealloc.但是,如果你有任何需要特殊处理的非对象ivars(例如你需要的分配缓冲区free()),你仍然需要处理那些dealloc.

此外,如果您将自己设置为任何对象的委托,则应该取消设置该关系dealloc(这是关于调用的一点[obj setDelegate:nil]).关于在未使用ARC编译的类上执行此操作的说明是对弱属性的认可.如果类明确标记其delegate属性,weak那么您不必执行此操作,因为弱属性的性质意味着它将为您填充.但是如果属性被标记,assign那么你应该在你的内容dealloc中将其清零,否则该类会留下一个悬空指针,如果它试图向其委托发送消息,它可能会崩溃.请注意,这仅适用于非保留关系,例如委托.

  • @Sulthan:是否在dealloc中使用setter是一个巨大的蠕虫,但我的立场基本上归结为:你想在dealloc中尽可能少地调用*代码.Setter倾向于通过覆盖子类,或通过KVO或其他机制来包括副作用.特别应该像瘟疫一样避免dealloc中的副作用.如果您可以从dealloc中删除方法调用,则应该这样做.这简化为:不要在dealloc中调用setter. (7认同)
  • @emfurry:它可能没有,因为当你的视图控制器死亡时,视图本身不应该在视图层次结构中,不应该做任何事情,但最好不要做出假设.如果异步调度的视图稍后要完成,并且视图本身最终会在短时间内超过其视图控制器(例如由于异步工作暂时保留视图),该怎么办?最好不要让代表安全.事实上,如果所讨论的视图是一个`UIWebView`,那么文档明确指出你需要将委托取出. (4认同)
  • 我不同意关于不在使用MRC的dealloc中使用setter的声明.Apple不推荐它,但他们也会在代码中使用它.实际上,您可以通过不使用setter来创建新问题.关于它有几个重要的讨论.什么是重要的是正确地写入setter(如果你传递一个nil值它必须正确行事)并且有时会观察deallocation的顺序. (4认同)
  • @zeiteisen:不."unsafe_unretained"完全等同于`assign`属性,是MRR下委托关系的正常行为,这些行为需要填写. (3认同)
  • 这很有道理!让我问你这个问题:我遇到的一个常见情况是我有一个`MyController:UIViewController`类,它创建并拥有一个UIView,并将视图的委托设置为自身.它是该观点的唯一保留所有者.当控制器被解除分配时,视图也应该被解除分配.如果委托指针悬空,那么它是否重要? (2认同)