Редактиране на NSManagedObject в дублиран контекст, за да го обедините по-късно

Когато потребител докосне два пъти изглед в моето приложение, uipopovercontroller му представя полетата, които той може да редактира. (Подобно на приложението за календар на iPad)

Изгледът представлява NSmanageobject. За да мога да отменя операциите, извършени в uipopovercontroller, идеята ми беше следната:

1) създайте „editManagedObjectContext“ в моя контролер за изглед за popover и му дайте persistentstorecoordinator на моя основен контекст, използван в моето приложение.

editContext = [[NSManagedObjectContext alloc] init];
[editContext setPersistentStoreCoordinator:[myContext persistentStoreCoordinator]];

2) извличане на обекта, представен на докоснатия изглед (Задача*) от новия "editContext"

task = [editContext objectWithID:[taskOrNilForNewTask objectID]];

3) Използвайте тази задача, за да извършите цялото редактиране и когато потребителят приключи, той може или:

  1. Отменете цялата операция по редактиране. Това просто ще отхвърли editContext и ще се върне.
  2. Запазване. След това това ще обедини редактирания контекст с оригиналния контекст чрез mergeChangesFromContextDidSaveNotification : По този начин ще извърши промените в съответната задача в оригиналния контекст.

Проблемът е, че task = [editContext objectWithID:[taskOrNilForNewTask objectID]]; води до обект с грешка. И по-късно, когато се опитам да осъществя достъп до свойствата на обект на задача, получавам или грешката BAD_EXC, или обектът ми на задача изглежда е от някакъв странен тип, вариращ от: CALayer, NSCFData,...

Мисълта ми беше, че може да се наложи първо да запазя оригиналния контекст, но това води до приблизително същите грешки. Но тъй като запазих точно преди да направя editContext, реших, че операцията за запазване може да се извърши в друга нишка и това може да е причина?

Просто не мога да разбера какво правя погрешно и се надявам, че можете да дадете някакъв съвет.

Моят подход се основаваше на подхода в кодовата проба на CoreDataBook от Apple (rootviewcontroller.m - (IBAction)addBook:)


person user558802    schedule 21.04.2011    source източник
comment

Под Linux CMake преглежда флаговете на компилатора, за да определи дали компилирате за 32-битов или 64-битов. Можете да предадете тази информация, като зададете информацията CMAKE_C_FLAGS и CMAKE_CXX_FLAGS при стартиране на cmake:

cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32

Преносимият начин да определите дали cmake генерира 32-битов или 64-битов проект тогава е да направите запитване към CMAKE_SIZEOF_VOID_P променлива, напр.:

if (CMAKE_SIZEOF_VOID_P EQUAL 8)
   # 64-bit project
else()
   # 32-bit project
endif()
  -  person Matthias Bauch    schedule 21.04.2011
comment
self.task = [editContext objectWithID:[taskOrNilForNewTask objectID]]; Поправих го и нямам представа защо.   -  person user558802    schedule 21.04.2011


Отговори (1)


Вашият проблем беше, че objectWithID: връща автоматично освободен обект, който след това съхранявахте в ivar, без да го запазвате. По-късно системата го освободи и или сте завършили с боклук, който ви дава EXC_BAD_ACCESS, или сте приключили случайно с различен обект на същото място в паметта. Грешките, които описахте, показаха това ясно.

Причината self.task да го коригира е, че свойството self.task е обявено за запазване, така че присвояването чрез свойството автоматично извършва необходимото запазване. Имайте предвид, че ако не го пускате в dealloc, тогава ще изтече памет.

person Anomie    schedule 21.04.2011