1

Представьте себе приложение для социальной фотографии, такое как Instagram. Вы видите одну из фотографий вашего друга в своем фиде. Эта фотография сохраняется в CoreData как что-то вроде этого:Сохранение CoreData NSManagedObject new

Photo (NSManagedObject) 
Attributes: id, imageURL 
Relationships: comments (set of Comment objects), likes (set of Like objects) 

У меня есть контроллер представления, который имеет ссылку на объект Фото. Этот контроллер просмотра также обрабатывает действия для симпатий и комментариев к фотографии.

Итак, когда кому-то нравится фотография, поток таков: Отправьте на сервер. Если сообщение API успешно выполнено, обновите объект Photo в CoreData с помощью любой новой информации, полученной с сервера, которая будет включать в себя новую. На этом этапе фото должно иметь еще один объект Like, связанный с ним в CoreData, чем до того, как я нажал аналогичную кнопку.

Теперь у меня проблема. Контроллеру просмотра необходимо обновить количество фотографий на фотографии. В блоке успеха, я делаю это:

self.likesLabel.text = [NSString stringWithFormat:@"%d likes", self.photo.likes.count]; 

Проблема заключается в том, что self.photo.likes.count докладывает 0 в этой точке (это был отличен от нуля, прежде чем я нажал на кнопку, как). Если я перейду в другое место и вернусь к этому экрану, подсчет будет правильно обновлен. Похоже, что Photo managedObject становится «грязным», когда я его обновляю. Обновление, вероятно, происходит в другом контексте (я использую Magical Record). Обновление выглядит примерно так:

NSManagedObjectContext* context = [NSManagedObjectContext MR_contextForCurrentThread]; 
Photo* photo = [Photo MR_findFirstWithPredicate:somePredicate inContext:context]; 
... 
photo.likes = likes; 
photo.comments = comments; 
[photo save:context]; 

Таким образом, вопрос, как я правильно держать объект фото обновленного в контроллере представления, так что я могу всегда надежно запрашивать количество подобных и комментарии? В общем, как вы всегда можете сохранить новую версию NSMangagedObject, учитывая, что она может быть обновлена ​​в других потоках/контекстах?

Я пробовал прослушивать NSManagedObjectContextObjectsDidChangeNotification, но я столкнулся с той же проблемой, когда фотографии 0 мне нравятся и комментируют, когда я получаю это уведомление.

+0

Вы должны объединить –

+0

выборки! = Обновление тоже BTW –

ответ

1

Одним из решений для этого сценария, который я часто использую, является KVO. В вашем случае я бы заметил свойство «любит» на управляемом объекте. Вы можете найти стандартные статьи KVO о том, как это сделать должным образом. Однако это всего лишь половина истории. Таким образом, для того, чтобы эти значения изменились для вас правильно, NSManagedObjectContext, который «управляет» этим свойством, должен сам получать обновления. В этом случае слияние происходит с событиями NSManagedOjbectContextDidSaveNotification в случае контекста изоляции потоков или вступает в действие правила родительского/дочернего слияния. Дело в том, что вы могли бы внести изменения в фактические данные в любом контексте вашего приложения. Это зависит от вас, чтобы объединить эти изменения в контексте, о котором вы сейчас заботитесь (возможно, о том, что отображается на экране).

Все, что сказал, MagicalRecord должен иметь некоторую сборку методов, которые уже обрабатывают эту половину проблемы для вас. Если нет, убедитесь, что ваш контекст, отображающий информацию об использовании, обновляется должным образом, когда фоновый контекст сохраняется. Следует помнить, что вам нужно обновить контекст, и как только контекст сменится новыми изменениями при обновлении, ваши методы KVO будут срабатывать с соответствующими значениями.

1

слушать и применять слияние, сделанные в других контекстах

#pragma mark - Core Data stack 

- (void)mergeChanges:(NSNotification *)notification { 
    // Merge changes into the main context on the main thread 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:MyMainContextMergedChangesNotification object:nil]; 
    }); 
} 

после слияния вы можете обновить GUI


Alternativly/дополнительно можно заставить контекст, чтобы обновить объект из БД призванию refreshObject:

+0

выборка не обновит контекст ' собственный кеш! –

+0

Спасибо за предложение. Я просто попробовал это. Я получаю уведомление. self.photo.likes.count все еще равен нулю даже после вызова [self.photo.managedObjectContext mergeChangesFromContextDidSaveNotification: уведомление]; – soleil

+0

weird - обратите внимание, что слияние isync (!) –

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