Имам многопоточно приложение, където трябва да обединя частен контекст с основния контекст, който от своя страна е свързан с контролера за постоянно съхранение.
Също така имам нужда да създавам временни обекти, които НЕ се управляват (докато по-късно реша да ги управлявам).
Първо се опитах да създам моите временни обекти, както следва;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:myMainQueueContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
След като реша да запазя обекта или не, аз просто;
[privateContext insertObject:user];
Преди да направя приложението многонишково, това работеше страхотно, но сега, след като леко разкъсах нещата и добавих многонишкова паралелност от дъщерен/родителски контекст, резултатът НЕ е според очакванията.
Като гледам „registeredObjects“ на контекста, мога да видя, че моят създаден и сега вмъкнат потребител се управлява в privateContext. След като го запазя, основният контекст се променя съответно и мога да видя, че има промени и че вече има един обект в регистрираните обекти.
Но като се вгледаме по-отблизо в ТОЗИ регистриран обект в основния контекст, разкриваме, че той е изпразнен. Без съдържание. Всички атрибути са нула или 0 в зависимост от типа. Следователно може да се очаква, че това може да се дължи на това, че objectId не е същият... но е ;( Това е същият обект. Но без съдържание.
Опитах се да получа някаква информация относно това безпокойство в друга публикация тук, но без успех.
Дъщерните контекстни обекти стават празни след сливане с родител/ основен контекст
Както и да е, най-накрая накарах нещата да работят, като промених начина, по който създавам обектите си;
User* user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:privateContext];
Изведнъж дъщерните ми обекти се обединяват с mainContext, без да губят съдържанието си, по неизвестни за мен причини, но за съжаление това също доведе до факта, че вече не мога да създавам временни неуправляеми обекти... ;( Четох, че Маркъс Зара подкрепи моя първи подход, когато става въпрос за създаване на неуправляеми обекти, но това не работи с обединяването на контексти в моето многонишково приложение...
Очаквам с нетърпение всякакви мисли и идеи -- аз ли съм единственият, който се опитва да създаде временни обекти в асинхронна работна нишка, където искам само да управлявам/обединявам подгрупа от тях до mainContext?
РЕДАКТИРАНЕ
Конкретен код, показващ какво работи и по-важното какво НЕ работи;
//Creatre private context and lnk to main context..
NSManagedObjectContext* privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
//Link private context to main context...
privateManagedObjectContext.parentContext = self.modelManager.mainManagedObjectContext;
[privateManagedObjectContext performBlock:^()
{
//Create user
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
[user setGuid:@"123123"];
[user setFirstName:@"Markus"];
[user setLastName:@"Millfjord"];
[privateManagedObjectContext insertObject:user];
//Debug before we start to merge...
NSLog(@"Before private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
NSLog(@"Before private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);
for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
NSLog(@"Registered private context object; %@", object);
//Save private context!
NSError* error = nil;
if (![privateManagedObjectContext save:&error])
{
//Oppps
abort();
}
NSLog(@"After private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
NSLog(@"After private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);
for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
NSLog(@"Registered private context object; %@", object);
for (NSManagedObject* object in [self.modelManager.mainManagedObjectContext registeredObjects])
NSLog(@"Registered main context object; %@", object);
//Save main context!
[self.modelManager.mainManagedObjectContext performBlock:^()
{
//Save main context!
NSError* mainError = nil;
if (![self.modelManager.mainManagedObjectContext save:&mainError])
{
//Opps again
NSLog(@"WARN; Failed saving main context changes: %@", mainError.description);
abort();
}
}];
}];
Горното НЕ работи, тъй като създава временен обект и след това го вмъква в контекста. Този лек мод обаче кара нещата да работят, но ми пречи да имам временни обекти...;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:privateManagedObjectContext];
Затова се чудя; каква е разликата? Очевидно трябва да има някаква разлика, но не я разбирам.