在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訊息放入到池中的,當然這一切對於開發人員都是不可見的,我們也要注意減少使用這樣的語句。
本文出自 “關東升” 部落格,請務必保留此出處http://2009315319.blog.51cto.com/701759/1132754