[英]Why this kind of release doesn't work?
我有一個關於以下方面的新手問題:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *anArray;
anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]];
//here dictionary is of type NSDictionary, initialized in another place.
AnObject *obj = [[AnObject alloc] init];
obj = [anArray objectAtIndex:0];
[anArray release];
return obj.title;
}
如果我按原樣運行,則會收到錯誤消息。 如果我不輸入[anArray版本],則效果很好。 我不太明白為什么會這樣?
謝謝。
您絕對必須閱讀並理解 Cocoa內存管理規則 ,尤其是指出以下內容的基本規則:
如果使用名稱以“ alloc”或“ new”開頭或包含“ copy”(例如alloc,newObject或mutableCopy)的方法創建對象,或者向其發送保留消息,則您擁有該對象的所有權。 您有責任使用release或autorelease放棄您擁有的對象的所有權。 任何其他時間收到對象時,都不得釋放它。
現在,看看如何掌握anArray。 您使用了方法objectForKey:它不以alloc開頭,也不是new,也不包含副本。 您也沒有保留anArray。 因此,您不擁有anArray。 您不得釋放它。
上面引用的規則是有關在不進行垃圾回收的情況下在iPhone或Mac上使用Cocoa進行編程的最重要的知識。 這里的其他海報之一是首字母縮略詞NARC(新Alloc保留副本)作為輔助備忘錄,非常方便。
讓我們將規則應用於代碼中名為obj的變量。 您是通過調用alloc獲得的,因此您有責任釋放它。 但是,然后通過調用objectForIndex再次獲得它(覆蓋先前的值):因此在此之后,您不能釋放它。 但是,第一個值確實需要釋放,現在已經泄漏。 實際上,分配行是不必要的。
您不需要釋放anArray,因為您沒有創建它。 字典只是給您一個指向它的指針。
您這樣做,似乎在創建AnObject時發生了內存泄漏。 在下一行中,將變量“ obj”重新分配為從anArray獲得的變量。 但是您尚未釋放在上一行創建的AnObject。
我認為您的代碼應如下所示:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *anArray;
anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]];
//here dictionary is of type NSDictionary, initialized in another place.
obj = [anArray objectAtIndex:0];
return obj.title;
}
您無需釋放尚未創建的內容。
anArray
不是由您分配,保留,復制或新增的,因此您無需釋放它。
另外,您還有一個泄漏,您在其中使用alloc / init創建一個全新的AnObject
實例,然后從數組中直接為其分配一個新值。
您的代碼應如下所示:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *anArray;
anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]];
//here dictionary is of type NSDictionary, initialized in another place.
AnObject *obj = [anArray objectAtIndex:0];
return obj.title;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.