请参阅以下代码我想知道如何取消分配单元格。根据我的理解,每个保留的每个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];
}
答案 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。