1

有些東西我似乎沒有得到關於iOS的屬性和內存管理!在我的AppDelegate中,我想要一個NSString *屬性:
- 我已經在.h文件中聲明瞭這種方式:@property(nonatomic,copy)NSString * myString;
- 和synthetized它在.M哪個對象向我的媒體資源發送了「發佈」消息?

我的一個方法,使用這樣的特性:

myString = [notificationDictionary objectForKey:@"myKey"]; 

(notificationDictionary作爲的NSDictionary *我的應用得到了中:didFinishLaunchingWithOptions:的launchOptions詞典與關鍵UIApplicationLaunchOptionsRemoteNotificationKey)

我認爲這意味着我的AppDelegate擁有自己的副本myString與保留計數爲1,對不對?

然後另一個方法試圖訪問屬性,但我得到一個EXC_BAD_ACCESS異常。

爲了100%確定發生了什麼事情,我多次保留了自己的屬性,並在每次訪問時顯示其保留計數的值:保留計數在我給出值的方法我的財產和我閱讀它的方法。

哪個對象將釋放方法發送到我的字符串?

回答

4

這條線:

myString = [notificationDictionary objectForKey:@"myKey"]; 

是否利用你的合成屬性訪問的。它只是直接設置實例變量,並繞過自動複製行爲。

爲了利用你的屬性訪問,你需要添加self.如下:

self.myString = [notificationDictionary objectForKey:@"myKey"]; 

更新:我更詳細地回答了類似的問題在這裏:why-does-this-property-need-the-retain?

更新#2:爲了進一步解釋,發送釋放消息到您的01的「神祕對象」變量實際上是NSAutoreleasePool的實例,很可能是與主線程關聯的池。由[notificationDictionary objectForKey:...]返回的值是自動釋放的,因此當您將此值分配給myString時,它只會持續到當前運行循環結束。當運行循環結束時,它會消耗自動釋放池,將release發送給任何已標記爲autorelease的對象。發生這種情況後,myString中的指針值引用已釋放的一塊內存。這種類型的死指針通常被稱爲殭屍。當您嘗試將消息發送給殭屍時,通常會發生EXC_BAD_ACCESS異常。

+0

哇!再次感謝 !這是我真正需要知道的! :) (儘管我認爲蘋果文檔對他們的API做的很好,但我認爲他們關於基本Objective-C概念的文檔很難找到並且相當具有說服力)。 無論如何,再次感謝! – 2010-07-29 10:51:21

+0

不用擔心! ':)'如果你正在尋找關於基本概念的一些閱讀材料,那麼一個好的開始就是Apple的內存管理指南:http://developer.apple.com/mac/library/documentation/cocoa/conceptual/MemoryMgmt /MemoryMgmt.html – 2010-07-29 11:00:39