Какой объект отправил сообщение "release" в мою собственность? - PullRequest
1 голос
/ 29 июля 2010

Есть что-то, чего я не понимаю в свойствах и управлении памятью с iOS!

В моем AppDelegate я хочу свойство NSString *:

  • Я объявил это таким образом в файле .h:

    свойство @ (nonatomic, copy) NSString * myString;

  • и синтезировал его в.m.

Один из моих методов использует свойство, подобное этому:

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

(notificationDictionary - NSDictionary*, полученное в application:didFinishLaunchingWithOptions: s launchOptions словарь с ключом UIApplicationLaunchOptionsRemoteNotificationKey)

Я думаю, это означает, что у моего AppDelegate есть собственная копия myString с счетом сохранения 1, верно?

Затем другой метод пытается получить доступ к свойству, но я получаю исключение EXC_BAD_ACCESS.

Чтобы быть на 100% уверенным в происходящем, я много раз сохранял свое свойство и отображал значениеего счет сохранения при каждом доступе: счет хранения уменьшается где-то между методом, в котором я присваиваю значение своему свойству, и методом, в котором я его читаю.

Какой объект отправил метод release в мою строку?

1 Ответ

4 голосов
/ 29 июля 2010

Эта строка:

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

Использует ли не ваш метод доступа к синтезированному свойству.Он просто устанавливает переменную экземпляра напрямую и обходит режим автоматического копирования.

Чтобы использовать средства доступа к своим свойствам, вам необходимо добавить self. следующим образом:

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

Обновление: Я ответил на аналогичный вопрос более подробно здесь: почему-это-свойство-нужно-сохранить?

Обновление № 2: Чтобы пояснить немного подробнее, «загадочный объект», который отправляет сообщение о выпуске в вашу переменную myString, на самом деле является экземпляром NSAutoreleasePool , скорее всего, пул, связанный с вашим основным потоком.Значение, возвращаемое [notificationDictionary objectForKey:...], автоматически высвобождается, поэтому, когда вы присваиваете это значение myString, оно будет действовать только до конца текущего цикла выполнения.Когда цикл выполнения завершается, он истощает пул автоматического выпуска, отправляя release любым объектам, которые были помечены для автоматического выпуска.После того, как это произошло, значение указателя в myString ссылается на освобожденный блок памяти.Этот тип мертвых указателей обычно называют зомби.Исключение EXC_BAD_ACCESS обычно возникает при попытке отправить сообщение зомби.

...