В моем приложении я записываю несколько строк в базу данных по умолчанию, например:
[[NSUserDefaults standardUserDefaults] setObject:@"Hi" forKey:@"GREETING"];
Когда я вызываю несколько раз в течение времени жизни моего приложения, я заканчиваю с ошибкой в консоли после перехода через этот код:
NSString *val = [[NSUserDefaults standardUserDefaults] objectForKey:@"someKey"];
Вот подробнее:
Как видите, у меня точка останова находится точно в строке с вызовом метода -stringForKey:
из NSUserDefaults
. После перешагивания уже происходит вылет! Нет возможности даже прочитать, что находится в val
. Он освобожден!
Это происходит с ЛЮБОЙ строкой, которую я вставляю в NSUserDefaults, из ВЕЗДЕ, и я не делаю ничего плохого с управлением памятью. Инструмент утечек идеален, как и результаты статического анализатора Clang.
Ошибка консоли:
*** -[CFString retain]: message sent to deallocated instance 0x610ba10
Верхняя часть трассировки стека в отладчике после сбоя: (верхняя строка читает пересылку )
символы машинного кода :
А теперь ДЕЙСТВИТЕЛЬНО странная часть: у меня есть контроллер представления, который загружает тяжелый пользовательский интерфейс. Когда я уничтожаю это представление и загружаю его, а затем снова уничтожаю и загружаю снова, ТО NSUserDefaults мертв. Сбой, как только я хочу прочитать строку из NSUserDefaults. Это абсолютно всегда одно и то же поведение.
Я подумал, что может быть утечка памяти, которая съедает всю оперативную память. Но это происходит на большой машине разработки, а также на iPad. Выпустите и перезагрузите представление два раза, и NSUserDefault имеет этот дефект.
Чтобы убедиться, что это не моя вина, я переписал свой код записи NSUserDefaults примерно так:
[[NSUserDefaults standardUserDefaults] setObject:[theString copy] forKey:key];
Но, тем не менее, я получаю освобожденные строковые экземпляры из NSUserDefaults! На тренажере и на устройстве! Кроме того, некоторые из тех строк, к которым я пытаюсь получить доступ, были записаны по умолчанию при инициализации приложения в + (void) initialize
NSDictionary *preSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
@"Hollywood", @"defaultCity",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:preSettings];
Поэтому, даже если я не изменю эту строку для ключа @ "defaultCity, и я хочу доступ к нему через некоторое время (когда я дважды перезагружал это толстое представление), я получаю освобожденный экземпляр из NSUserDefaults.
Я также попытался повторно инициализировать все это, вручную вызвав свой метод в делегате приложения, который регистрирует это словарь по умолчанию с NSUserDefaults. Ничего не помогает.
Я на 100% уверен, что нет утечек памяти (чрезмерно протестирован с помощью инструмента Leaks). Я не понимаю, почему это происходит.Я также пытался сохранить эти строки 5 раз, прежде чем записывать их в NSUserDefaults (что в любом случае было бы глупо), но безуспешно.
Идеи?
ПРОБЛЕМА РЕШЕНА!
Одна из строк, возвращенных NSUserDefaults, была назначена к удерживающей собственности. Я забыл добавить себя.
перед self.theProperty = theStringFromNSUserDefaults
, что привело к чрезмерному освобождению этой строки в -dealloc, когда представление было освобождено.
Странно, однако, что я смог загрузить, уничтожить, загрузить, уничтожить это Посмотреть. И , затем это произошло при первой попытке чтения любой строки из NSUserDefaults. Это похоже на то, как освобожденная строка распространяется через словарь по умолчанию или базу данных по умолчанию и разрушает все, приводя в движение алгоритмы NSUserDefaults и NSDictionary.
После исправления этой единственной ошибки все работало нормально. Включая также доступ ко всем остальным строкам в NSUserDefaults. Работает, но до сих пор остается загадкой, как это единственное забытое я.
оказал такое большое влияние.
Спасибо всем, кто помог решить эту проблему. Ты спас меня от сердечного приступа. Я был так близок к этому. Что ж, пора купить кое-что нового ... мой офис выглядит как комната Звездных Врат после нападения Гоа'улдов.