iPhone-解除锁定-发布与否

iPhone-解除锁定-发布与否,iphone,memory,memory-management,release-management,dealloc,Iphone,Memory,Memory Management,Release Management,Dealloc,想知道是否有经验的人可以解释得更多一些。我见过……的例子 [view release]; view = nil; …在(无效)解除锁定内 区别是什么?一个比另一个好吗? 最好的方法是什么 在进行重新计数测试时,我个人看到nil将计数从3降到0,但release只将计数从3降到2。我认为两者都使用是一种安全网。只有发布到位后,如果您拧紧了引用计数管理,您可能会遇到问题。您可以释放一个对象,将其内存返回给系统,但指针仍然有效 使用nil可以保证程序不会崩溃,因为向nil发送消息不起任

想知道是否有经验的人可以解释得更多一些。我见过……的例子

  [view release];

  view = nil;  
…在(无效)解除锁定内

区别是什么?一个比另一个好吗? 最好的方法是什么


在进行重新计数测试时,我个人看到nil将计数从3降到0,但release只将计数从3降到2。

我认为两者都使用是一种安全网。只有
发布
到位后,如果您拧紧了引用计数管理,您可能会遇到问题。您可以释放一个对象,将其内存返回给系统,但指针仍然有效


使用
nil
可以保证程序不会崩溃,因为向
nil
发送消息不起任何作用

您所看到的可能是:

1) [foo release];
2) self.bar = nil;
3) baz = nil;
  • 正在释放对象,通过实例变量
    foo
    访问它。实例变量将成为悬空指针。这是dealloc中的首选方法

  • nil
    赋值给self上的属性
    bar
    ,实际上将释放该属性当前保留的任何内容。如果您有一个用于属性的自定义setter,则执行此操作,该setter应该清理的不仅仅是支持该属性的实例变量

  • 将用nil覆盖引用对象的指针
    baz
    ,但不会释放对象。结果是内存泄漏。永远不要这样做


  • 就代码内部的用法而言,在
    dealloc
    中,您不需要对属性进行赋值,
    releas
    ing就是您所需要做的一切

    - (void)dealloc {
        [myProperty release]; // don't need to assign since you won't have the object soon anyway
        [super dealloc];
    }
    

    如果未使用属性(其中self.property=nil也将释放对象),则应始终遵循将引用设置为nil的release by代码,如您所述:

    [view release]; view = nil;
    
    原因是它避免了引用无效的可能性。这是罕见的,也很难发生,但它可以发生

    这在viewDidUnload中更为重要,如果您正在释放IBOutlets,这是一个更现实的场景,在这种场景中,由于卸载视图时出现内存警告,引用可能会出错,然后视图中的一些其他代码试图在重新加载视图之前使用引用


    基本上,这只是一个很好的实践,如果你养成这样做的习惯,它会在某个时候避免崩溃。

    @bbullis22你已经看到restain计数从3下降到0,因为你将引用设置为零。然后你要求重新计算'nil',它是零。但是,以前被引用的对象具有相同的保留计数-1(由于将引用设置为nil)。
    使用release时,引用仍然引用同一个对象,因此在这种情况下,您会看到保留计数从3下降到2。

    因此,在viewdiload中使用数字3不会释放alloc对象的内存?不,它使用3)永远不会释放内存,除非您在Mac OS X上的垃圾收集obj-C中,否则执行self.bar=nil也可能导致内存泄漏。如果属性被定义为@retain,它将按照预期工作;如果将其定义为@copy,则存在内存泄漏。@AlBlue:不,它不会导致内存泄漏。使用“保留”或“复制”将具有相同的语义操作系统,以释放属性引用的上一个对象。唯一的区别是如何获得新的价值;'ivar=[newValue retain];`vs.
    ivar=[newValue copy]
    。两者都将通过简单的
    [ivar release]
    释放旧值。使用2)可能会有危险,这就是为什么首选1)的原因。如果setter被一个子类覆盖,那么现在正在调用其
    dealloc
    方法已被调用的子类中的方法。安全属性/ivar访问的一般规则是:1)直接从
    init
    dealloc
    和setter/getter中使用ivar。2) 所有其他访问都应该通过该属性。您建议同时拨打这两个电话吗?释放前为零或反之亦然?在释放前指定零意味着将释放发送给零(因此不会释放对象)。分配给nil是可选的(因为对象正在被释放,实例变量不应该再被引用)等等,最后一行不是应该是[super dealloc]吗?所以本质上对于具有属性的IVAR,我们可以这样做吗?-(void)dealloc{self.iVar=nil}您可以,尽管您过去被告知不要在dealloc中使用setter,以免产生副作用。。。但是现在,内部类变量可以在必须使用setter的地方自动创建,我想在dealloc中使用该方法将变量设置为nil是可以的。您仍然可以引用合成的实例变量,您不必在dealloc中使用setter。很好的一点是,实际上您不应该在dealloc中使用setter。