如何在Objective C中解除分配并释放这些变量?

时间:2011-10-06 21:41:49

标签: objective-c xcode4

请参阅以下代码我想知道如何取消分配单元格。根据我的理解,每个保留的每个alloc和release都必须有de-alloc。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"UITableViewCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc]
                 initWithStyle: UITableViewCellStyleSubtitle
                 reuseIdentifier: CellIdentifier] autorelease];
    }
    cell.textLabel.text = [dataArray objectAtIndex:indexPath.row];    return cell;
}

从下面的代码中我做了正确的事情取消分配dataArray ,或者它应该是release还是两者兼而有之。
接口

@interface myViewController : UIViewController
{
    NSArray *dataArray;
}

@property(retain,nonatomic) NSArray *dataArray;
@end

来自实施

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataArray=[[NSArray alloc] initWithObjects:@"XXX",@"YYY",@"ZZZ",nil];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [self.dataArray dealloc];
}

3 个答案:

答案 0 :(得分:3)

  

根据我的理解,每个alloc必须有一个de-alloc   每次保留都会释放。

你理解不正确。每个保留都必须有一个版本,但是你没有/不应该明确地解除分配。

当你需要一个对象时你应该保留它([[XX alloc] init]为你执行初始保留)。当您不再需要某个对象时,您应该释放它上面的保留。

这些是简单的规则。没有太多精美的印刷品,但是该语言的许多功能可以帮助您完成规则,还有一些“交易技巧”可供学习(最明显的是“自动释放”如何工作)。

答案 1 :(得分:2)

在您的示例中,您分配的单元格将自动释放,因为您已向对象发送了自动释放消息。所以你不必担心它的内存被释放 - 这将自动发生。

至于你的第二个问题,一般来说,你不应该直接调用dealloc。当对象的保留计数变为零时,系统会为您调用dealloc。您应该阅读以下文章,该文章以非常明确的方式很好地解释了内存管理:http://interfacelab.com/objective-c-memory-management-for-lazy-people/

您发布的具体代码有两个问题。首先,根据我上面所说的,dealloc应该替换为释放调用。其次,实际上存在内存泄漏:当您分配dataArray对象时,它会获得保留计数1.但是您将其分配给使用“retain”属性定义的属性。因此该属性的setter将再次保留该对象,将其保留计数设置为2.当您最终释放时,它将返回到1,但不会返回到零,因此它不会被释放。

要解决此问题,请将其分配给支持该属性的实例变量,而不是将alloc'd对象分配给该属性。默认情况下,实例变量将与属性具有相同的名称,因此您只需执行

dataArray = [[NSArray alloc] initWithObjects:@"XXX",@"YYY",@"ZZZ",nil];

如果在合成属性时明确地为实例变量指定了名称(通过执行@synthesize dataArray = _dataArray之类的操作,则使用该名称。

另一个选择是不分配/初始化数组,而是使用arrayWithObjects class method on NSArray。您从中获取的对象将被自动释放,因此您不必担心管理它。

答案 2 :(得分:0)

在第一个中你不必担心释放那个单元格,因为它将由TableView释放,tableView实际上只保留了每次重复使用的固定少量单元格。

对于第二个示例,只需使用返回自动释放对象的便捷方法:

self.dataArray = [NSArray initwithObject:myObject];

因为你使用了一个retain setter,所以最后保留计数为1,这应该在dealloc方法中释放,如下所示:

- (void) dealloc
{
    [dataArray release];
    [super dealloc];
}

你不应该直接在viewDidUnload上调用dealloc,你需要做的是对于mainView的任何保留的subView,使用setter来释放它,如下所示:

self.myView = nil;

这将释放前一个值并指向nil。