iPhone dealloc和viewDidUnload问题

时间:2012-03-26 18:59:26

标签: iphone objective-c ios

我有一个关于dealloc()和viewDidUnload()方法的快速问题。我注意到很多代码示例,人们似乎做了不同的事情。

另外,我可能会补充说ARC不是一种选择。

(1)我应该在dealloc()方法中将所有属性设置为nil,包括IBOutlets。例如,我应该释放实例变量[_myArrary release]并设置self.myArrary = nil。

(2)在viewDidUnload中,我想我必须将所有IBOutlets设置为nil,以及在viewDidLoad中创建的任何内容。但是,myString怎么样,让我们​​说在调用viewDidLoad之后它在另一个方法中初始化了。我应该把它设置为零吗?

如果我声明了一些属性:

@property (nonatomic, retain) IBOutlet UITableViewCell *myTableCell;
@property (nonatomic, retain) IBOutlet UILabel *myLabel;
@property (nonatomic, retain) NSArray *myArrary;
@property (nonatomic, retain) NSString *myString;

I synthesize them as such:

@synthesize myArrary = _myArrary;
@synthesize myTableCell;
@synthesize myLabel;
@synthesize myString;

- (void)viewDidLoad
{
    [super viewDidLoad];

    _myArrary = [NSArrary alloc] initWithObjects:@"testObject", nil];
}

- (void)viewDidUnload
{
    self.myArrary = nil;

    self.myTableCell = nil;

    self.myLabel = nil;

    [super viewDidUnload];
}

- (void)dealloc
{   
    [_myArray release];

    [super dealloc];
}

2 个答案:

答案 0 :(得分:4)

  1. 如果在dealloc中将属性/变量设置为nil,则无关紧要,因为一旦取消分配对象,您无论如何都无法访问它们。使用保留属性,执行

    self.varname = nil;

    将释放变量并将其设置为nil。很多人更喜欢只发布它们,我更喜欢将retain属性设置为nil以保持一致性。

  2. 在viewDidUnload中,您应该释放并设置为nil不需要的任何内容,并在视图再次加载时重新创建。这不是一个严格的规则,但是保持尽可能多的内存的良好做法。如果你的字符串将在viewDidLoad中重新创建,并且在再次加载视图之前你不需要访问它,那么你应该释放它(为了安全起见,我会把它设置为nil。)

    另外请注意,viewDidUnload并不总是在dealloc之前被调用。所以你应该释放每个属性/变量dealloc,即使它也被释放并在viewDidUnload中设置为nil。为了确保在释放类时不会泄漏,该代码的dealloc函数应如下所示:

    - (void)dealloc {
        [myTableCell release];
        [myLabel release];
        [_myArray release];
        [myString release];
    
        [super dealloc];
    }
    

    将它们设置为nil也是可以接受的,但仅当您使用合成的setter时,因为这也会释放变量。

    self.myLabel =  nil;
    

    很好,但是

    myLabel = nil;
    

    漏水。

答案 1 :(得分:2)

一般情况下,如果您的viewDidUnload在此期间未被释放,则您希望viewDidLoad发布可在ViewController中重新创建的任何内容。

dealloc中,您需要释放ViewController仍然拥有的任何内容。你不能假设首先调用了viewDidUnload,所以要防御。

另外请记住,向nil发送邮件并没有什么害处 - 但是将发布版发送给您不拥有的对象,或者将其多次发送给您拥有的对象会有很多危害。

由于你的属性是合成保留的,你可以避免自己发送release,只需使用setter将它们设置为nil(self.property = nil),当然假设你还没有添加任何额外的保留任何地方。

N.B。在viewDidLoad中,您已明确地将新创建的对象分配给您的属性已合成的iVar。不要这样做! 如果另一个对象在实例化和演示之间设置了属性,那么它将泄漏。只有当您确定这是正确的事情时才使用_ivar,并且您已经处理了所有边缘情况。

TL:DR - 在self.property = nilviewDidUnload中使用dealloc并且永远不会将新对象分配给_ivar,除非您先检查它已经nil {1}}或准备释放之前的值。