在viewDidUnload中设置为nil,但在dealloc中释放

| 我整天都在阅读为什么将viewDidUnload中的视图设置为nil并在dealloc中释放该视图。所有文章都在重复相同的内容。是的,我知道幕后说明有所不同,但是实际区别是什么? var =无 如果var是保留的属性,则回收内存var指向的旧对象。 将var设置为nil。 [var版本] 回收内存var指向。 var现在指向空,等于nil 对我来说,两种回收内存的方法都有相同的最终结果。那么,为什么要一个接一个呢?那里的每一本书都告诉我在
viewDidUnload
中设置为nil,在ѭ1release中释放。应当指出如果在ѭ0中释放视图并在ѭ1中取消视图会发生的坏事。 。H
#import <UIKit/UIKit.h>
@interface DisclosureDetailController : UIViewController {
 UILabel* label;
}
@property (nonatomic, retain) IBOutlet UILabel* label;
@end
.m
#import \"DisclosureDetailController.h\"
@implementation DisclosureDetailController
@synthesize label;
- (void)viewDidUnload {
 self.label = nil;
 // OR [self.label release];
 [super viewDidUnload];
}
- (void)dealloc {
 [self.label release];
 // OR self.label = nil;
}
    
已邀请:
首先,行
[self.label release];
不管您在哪里叫它都是绝对错误的。绝对不要在属性访问结果上致电ѭ7。这与写ѭ8exactly完全相同,我希望您能认出是错的。 您的代码示例应如下所示:
- (void)viewDidUnload {
    self.label = nil;
    [super viewDidUnload];
}
- (void)dealloc {
    [label release];
    [super dealloc];
}
如果我们先看ѭ10,那很简单。
self.label = nil;
是正确的。同样正确的是ѭ12。尽管不尽如人意,但写
[label release], label = nil;
也是可以接受的。最后一种形式不是很好,因为它绕过了setter方法,这可能比简单地释放属性要做更多的事情(例如,它可能维护关心属性值的内部状态)。它还绕过KVO通知。 真正的问题是在ѭ14中做什么。许多人建议说11英镑是完全可以的,实际上,这在大多数情况下都有效。问题是,其余时间将导致细微的错误。调用二传手可以完成两件事。首先是,如果手动实现setter方法,它可能会在您的类中引起副作用(即使您自己没有实现setter,也可能是子类)。第二个是它可以广播KVO通知。当您在ѭ14中时,这些东西都不需要。通过像ѭ17中一样直接释放ivar,可以避免潜在的副作用和KVO通知。     
实际差异如下。 通过使用属性访问器将属性设置为nil,将使综合方法在释放现有属性后抓住新的nil属性。
// we will take for granted that you synthesize this property
@property (nonatomic, retain) IBOutlet UILabel* label;
我们将使用属性访问器并将其设置为nil。
//This will in actuality set the new value of nil to the label variable after
//releasing the existing label that it had a retain count on.
self.label = nil; 
接下来我们将直接释放它
//This line on the other hand will merely release the label directly. 
//As soon as the label is deallocated you will have a handle to an invalid object. 
//(memory space that used to be your label)
[label release];
现在,我们将显示属性访问器的简化版本。 (不要从字面上使用)
//Simply put the following is an pseudo equivalent of the property setter.
[label release]
label = nil;
这里的重点是属性访问器处理释放它保留的标签。并将其设置为您要处理的任何内容(在本例中为nil) 因此添加以下代码
label = nil;
没有释放保留的对象将导致内存泄漏,并且您将在不再有指针的标签上保留计数。 注意:   另一件事要考虑。   任何为零的指针。将能够   接受消息。作为回报,他们   将以零答复。一个物体   另一方面被释放,因为   释放内存后   您发送给它的消息很可能   抛出一个错误。结果是   不可预料的。这是一个很好的理由   用于将属性设置为nil。   它不仅会处理发布   对于它持有的对象。但   它也会给你一个对象   可以安全地向其发送消息   起来 @WaltSellers好点 访问变量-无论变量是属性访问器还是实例变量。 -完全释放后。将导致\“ Undefined \”操作。这意味着访问可能会正常运行,或者可能破坏应用程序的其他部分,或者可能只是快速炸毁并终止有问题的应用程序。基本上,在释放后将变量设置为nil可以使您克服该错误。 与我分开的小费 为了克服对属性访问器和实例变量的误解,我只需@synthesize并告诉它设置变量名。
@synthesize label = _label;
这样做使我可以将self.label与实例变量区分开。因为您不再可以在没有前面的_的情况下直接访问label变量     

要回复问题请先登录注册