0

У меня есть ситуация, когда я вношу некоторые изменения в свойства NSManagedObject в основном потоке. Он относится к главному ManagedObjectContext приложения.NSManagedObjectContextDidSaveNotification не запускается в iOS 7

Мое приложение имеет включенное потокование, которое загружает данные, каждый поток имеет свой собственный ManagedObjectContext, созданный из последнего состояния одного PersistentStore во всем приложении.

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

- (void)backgroundMOCDidSave:(NSNotification*)notification 
{ 
    // Probable fix for: http://stackoverflow.com/questions/3446983/collection-was-mutated-while-being-enumerated-on-executefetchrequest 
    if (![NSThread isMainThread]) 
    { 
     [self performSelectorOnMainThread:@selector(backgroundMOCDidSave:) withObject:notification waitUntilDone:YES]; 
     return; 
    } 

    // We merge the background moc changes in the main moc 
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; 
} 

Регистрация для этого уведомления:

 [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(backgroundMOCDidSave:) 
                name:NSManagedObjectContextDidSaveNotification 
                object:nil]; 

Странные вещи происходят в прошивкой 7, хотя. Я доступ к NSManagedObject, который создается из главного MOC:

  • Когда я изменить свойство ManagedObject, который принадлежит к основному МОС (основная нить) и выполнить -save на -backgroundMOCDidSave: вызов не запускается
  • Когда Я не изменять любые свойства ManagedObject и просто выполнить -save операции по его MOC уведомления срабатывают

тот же код работает отлично в прошивкой 6. Независимо от того, будет ли сделано какие-либо изменения на ManagedObject или нет, когда a -save вызывает на MOC уведомление NSManagedObjectContextDidSaveNotification запускается.

Кто-нибудь сталкивался с этой проблемой раньше?

+0

Являются ли ваши фоновые контексты независимыми или вложенными из основного контекста? –

+0

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

+0

Как вы проверяете, запускается ли 'backgroundMOCDidSave:'? –

ответ

1

На данный момент я заметил одно, что не так, но я не уверен, что это вызывает вашу ошибку. NSManagedObjectContextDidSaveNotification отправлен в поток, на котором работает MOC, который вызывает save. Но слияние должно выполняться в потоке MOC-изменения слияния. В вашем случае он отлично работает, если изменения объединяются из фона в основной MOC, но не наоборот.

+0

Да, вы упомянули, это всего лишь утверждение моей точки. Что-то не так в реализации здесь? Уведомление DidSave должно было быть запущено на основном MOC, поскольку оно будет (было) записано в постоянное хранилище, не так ли? –

+0

Я подошел поближе, и я вижу, что ваша реализация не обрабатывает слияние изменений с основного на фоновый MOC. Вам нужен другой метод, например 'mainMOCDidSave'. Затем вам нужно изменить подписку на уведомления, чтобы зависеть от контекста. Вместо 'object: nil];' у вас должно быть два подписок: 'object: self.managedObjectContext];' и 'object: self.backgroundManagedObjectContext];' –

+0

Хорошо, я понимаю вашу точку зрения сейчас. Помимо основного MOC в основном потоке, я создаю MOC для каждого потока. Таким образом, потоки MOC не живут долго. Когда я получаю все данные с сервера, я уверен, что я вызываю -save на основном MOC только после этого, я создаю MOC для потока, это гарантирует, что MOC для потока создается из самого обновленного состояния постоянного хранилища. Но проблема для меня не во вторичных потоках, а в MOC.Скорее здесь изменения, внесенные в ManagedObject основного MOC, не запускают NSManagedObjectContextDidSaveNotification, когда я выполняю операцию. –

Смежные вопросы