awakeFromInsert вызывается дважды с вложенными контекстами
В этом проекте используются Mogenerator и Magical Record. Я обнаружил ошибку в том, что awakeFromInsert
звонят дважды. Я полагаю, один раз для каждого из моих контекстов. Это проблема, потому что мне нужно прослушивать NSNotifications для этого NSManagedObject следующим образом:
- (void)awakeFromInsert
{
// Listen for a return from background mode
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteringForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
Но функция get вызывается из awakeFromInsert дважды, что довольно раздражает. Я хочу вызвать метод ОДИН РАЗ, когда мой NSManagedObject впервые создан.
После поиска это решение, похоже, имеет большой смысл. Однако я не вижу, как я могу добавить категорию в NSManagedObject при использовании Mogenerator и MagicalRecord. Без некоторого сложного переопределения.
В магической записи MR_createEntity
звонки
if ([self respondsToSelector:@selector(insertInManagedObjectContext:)])
{
id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context];
return entity;
}
Есть более точное решение этой проблемы?
3 ответа
Ладно, это выглядит очень забавно, но, похоже, работает. Я создал следующие методы класса в своем читаемом человеком классе NSManagedObject:
+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ {
JWBoard *newobject = [super insertInManagedObjectContext:moc_];
[JWBoard awakeFromCreate:newobject];
return newobject;
}
+ (void)awakeFromCreate:(JWBoard *)board
{
// do setup stuff & add observers
}
Открыты для гораздо лучших решений!
Открыты для гораздо лучших решений!
Хотелось бы! Для Apple было бы достаточно просто не вызывать awakeFromInsert или, по крайней мере, предоставлять флаг, который является истинным в контексте "parentProcessSaveRequest". Если вы посмотрите на стек вызовов для не-первых вызовов awakeFromInsert
стек всегда содержит parentProcessSaveRequest
,
Вот какой-то ужасный код, доказывающий это:
- (void) awakeFromInsert
{
[super awakeFromInsert];
NSArray* stackArray = [NSThread callStackSymbols];
for (NSString* method in stackArray)
{
if ([method rangeOfString:@"_parentProcessSaveRequest"].location != NSNotFound)
{
NSLog(@"Parent insert %@",self.objectID);
return;
}
}
NSLog(@"First insert %@",self.objectID);
// Initialize here
}
И вывод журнала - objectId остается прежним:
2014-05-19 20:53:52.964 myApp[1891:a01f] First insert 0x6000000326c0 <x-coredata:///MyEntity/t496E9B17-E170-4A7C-B7D4-7D8B92433E1C2>
2014-05-19 20:53:53.531 myApp[1891:303] Parent insert 0xdca8000eb <x-coredata://7274869F-4BF3-4B8A-9270-A64E54476AAD/MyEntity/p14122>
2014-05-19 20:53:53.537 myApp[1891:303] Parent insert 0xdca8000eb <x-coredata://7274869F-4BF3-4B8A-9270-A64E54476AAD/MyEntity/p14122>
Кажется, работает для сохранения в любой из вложенных контекстов, которые у меня есть, безобразно, как это.
К сожалению, я не могу найти какой-либо разумный способ определить, вызывается ли awakeFromInsert в контексте parentProcessSaveRequest. Давай, Apple! Дайте нам флаг здесь.
Здесь самый простой: когда parentContext имеет значение null, означает, что при сохранении этого контекста вы можете использовать собственную логику, например, увеличивая номер таблицы
- (void)awakeFromInsert
{
if (!self.managedObjectContext.parentContext) {
//setting tableNumber
[self willChangeValueForKey:@"number"];
[self setPrimitiveNumber:tableNumber];
[self didChangeValueForKey:@"number"];
}
}