在MRR中释放对象通过release或autorelease消息实现,release消息会立刻使引用计数-1释放,发送 autorelease消息会使对象放入内存释放池中延迟释放,对象的引用计数并不真正变化,而是向内存释放池中添加一条记录,直到当池被销毁前会通知池 中的所有对象全部发送release消息真正将引用计数减少。
由于会使对象延迟释放,除非必须,否则不要使用autorelease释放对象,在iOS程序中默认内存释放池的释放是在程序结束,应用程序入口main.m文件代码如下:
int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
代码被包裹在@autoreleasepool {… }之间,这是池的作用范围,默认是整个应用。如果产生大量对象采用autorelease释放也会导致内存泄漏。那么什么时候autorelease是必须呢?我们看看下面代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @”CellIdentifier”; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } NSUInteger row = [indexPath row]; NSDictionary *rowDict = [self.listTeams objectAtIndex:row]; cell.textLabel.text = [rowDict objectForKey:@"name"]; NSString *imagePath = [rowDict objectForKey:@"image"]; imagePath = [imagePath stringByAppendingString:@".png"]; cell.imageView.image = [UIImage imageNamed:imagePath]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell; }
其中的cell对象不能马上release,我们需要使用它设置表视图画面。autorelease一般应用于为其它调用者提供对象的方法中,对象在该方法不能马上release,而需要延迟释放。
此外,还有一种情况下使用了autorelease,即前文提到的“类级构造方法”:
NSString *message = [NSString stringWithFormat:@"您选择了%@队。", rowValue];
该对象的所有权虽然不是当前调用者,但它是由iOS系统通过发送autorelease消息放入到池中的,当然这一切对于开发者都是不可见的,我们也要注意减少使用这样的语句。