iOS開發那些事-效能優化–autorelease的使用問題

智捷關東昇發表於2013-02-07

在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訊息放入到池中的,當然這一切對於開發者都是不可見的,我們也要注意減少使用這樣的語句。

相關文章