Основные данные - Как проверить, были ли освобождены свойства управляемого объекта? - PullRequest
3 голосов
/ 13 апреля 2010

Я создал программу, которая использует основные данные, и она прекрасно работает.

С тех пор я пытался переместить все мои основные вызовы методов данных и извлечь подпрограммы в отдельный класс. Затем моя основная программа создает экземпляр этого класса и выполняет некоторые базовые вызовы методов для этого класса, а затем класс выполняет все основные операции с данными за кулисами. Я сталкиваюсь с тем, что иногда я обнаруживаю, что, когда я беру управляемый объект из контекста, у меня будет действительный объект, но его свойства были освобождены, и я вызову сбой. Я играл с зомби и искал утечки памяти, и я понял, что цикл запуска, вероятно, отвечает за освобождение памяти, но я не уверен.

Есть ли способ определить, была ли освобождена эта память, и принудительно вернуть данные ядра, если мне нужно получить к ней доступ? Мой managedObjectContext никогда не освобождается, и fetchedResultsController также никогда не освобождается.

Я подумал, что, возможно, мне нужно использовать метод [managedObjectContext refreshObject: mergeData:] или метод [managedObjectContext setRetainsRegisteredObjects:]. Хотя у меня сложилось впечатление, что последний вариант может быть не лучшим выбором, так как он потребует больше памяти (насколько я понимаю).

Эти ошибки появлялись, только когда я перемещал вызовы основных данных в другой файл класса, и они случайны, когда они появляются.

Любое понимание будет оценено.

-Ryan

Ответы [ 4 ]

1 голос
/ 14 апреля 2010

Трудно понять, в чем заключается проблема, исходя из вашего описания, но вы можете обратиться к Руководству по управлению памятью Core Data . Вам не нужно беспокоиться об управлении памятью для управляемых объектов и их объектов (они автоматически выбираются и сбрасываются). Когда вы говорите о «свойствах», вы имеете в виду пользовательские свойства, поддерживаемые ivars? Если это так, они должны быть release d в didTurnIntoFault и alloc d по мере необходимости (вероятно, в методе доступа).

1 голос
/ 14 ноября 2011

Я боролся с подобной проблемой. Я использую класс управляемого объекта и хочу установить его свойства в зависимости от пользовательского ввода. Но иногда свойства, а иногда и весь управляемый объект были освобождены.

После прочтения документации Apple http://developer.apple.com/library/IOs/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMemory.html в главе «Роль контекста управляемого объекта» я узнал, что управляемые объекты освобождаются при завершении каждого цикла выполнения.

И есть золотой совет, чтобы установить

[myMangedObjectContext setRetainsRegisteredObjects:YES];

(Я должен был установить его в методе init (initWithNibName для меня) моего контроллера представления.)

Вы также должны оставить только те объекты, которые вам нужны, как описано в документации. Но прочитайте это сами.

Если я не прав, поправьте меня.

1 голос
/ 13 апреля 2010

Звучит так, будто вы не удерживаете предметы, которые хотите продолжать бродить. Если вы делаете что-то вроде этого:

NSArray *array = [moc executeFetchRequest:request error:&error];

вы не являетесь владельцем возвращенного массива, и он, скорее всего, исчезнет, ​​когда текущий пул автоматического выпуска будет очищен. Это произойдет, когда цикл выполнения завершит обработку текущего события.

Все это домыслы. Если вы хотите получить правильный ответ, вы должны опубликовать свой код.

0 голосов
/ 12 июня 2012

Я также создал класс, который обрабатывает все мои извлечения CoreData и прочее. Я столкнулся с парой гоч, так что вот несколько советов. (Если я делаю какие-либо ошибки управления памятью в этих примерах, пожалуйста, дайте мне знать.)

Две вещи:


1) Сделал метод «fetchFiredObject» в классе обработчика CoreData. Поэтому, когда я хочу получить управляемый объект, который имеет все свои переменные и является, так сказать, «полностью пернатой птицей» вместо выполнения:

aManagedObject *myManagedObject = [myCoreDataHandler.managedObjectStorageArray objectAtIndex:1];
int x = myManagedObject.someVariable.intValue;

вместо этого я делаю:

aManagedObject *myManagedObject = [myCoreDataHandler fetchFiredObjectAtIndex:1];
int x = myManagedObject.someVariable.intValue;

И в методе fetchFiredObjectAtIndex: i в myCoreDataHandler мы идем в массив, находим ключ объекта по индексу i, затем выполняем fetchRequest для этого ключа объекта и возвращаем недавно выбранный управляемый объект, чтобы он не имел были повреждены или освобождены и т. д.: D


2) Когда я создаю новый дочерний viewController, я заполняю его значение "myCoreDataHandler" из родительского элемента при создании. Однако это происходит в следующей строке кода после строки кода, которая создает новый viewController. Поэтому любой код в дочернем viewDidLoad, который пытается использовать методы myCoreDataHandler, вернет пустые объекты, потому что viewDidLoad завершает до следующей строки кода родителя, где он устанавливает значения глобальных переменных в дочернем объекте. Поэтому убедитесь, что вы не обращаетесь к своему «Базовому объекту обработки данных» из viewDidLoad или каких-либо локальных методов, вызываемых viewDidLoad! Вместо этого вызывайте их из родительского объекта после создания нового viewController.

...