В моем приложении я использую CoreData для хранения и отображения данных с помощью NSFetchedResultsController.Как разбить основные потоки данных Data Data на слияние изменений?
Я следил за учебниками от raywenderlich, чтобы сделать это, и это много кода, но он работает нормально вообще - будет публиковать его части, когда это необходимо. Я застрял на одной проблеме, которую я не могу понять.
Данные, отображаемые внутри UITableView в сочетании с NSFetchedResultsController, могут быть обновлены в фоновом режиме - и вот здесь началась моя проблема.
Я делаю подход Pull-to-refresh и запускаю загрузку в фоновом режиме в отдельной теме. Он использует собственный NSManagedObjectContext, созданный для этого потока и сохраняющий его после создания всех объектов.
Вот код:
- (void)refresh:(id)sender
{
[ServerConnection downloadContactsForToken:token success:^(NSDictionary* responseObject)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSManagedObjectContext* context = [[[AppManager sharedAppManager] createManagedObjectContext] retain];
NSArray* responseContacts = responseObject[@"contacts"];
[responseContacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//ContactDB is NSManagedObject
[[[ContactDB alloc] initWithDictionary:obj andContext:context] autorelease];
}];
[context save:nil];
[context release];
dispatch_async(dispatch_get_main_queue(), ^{
[self.refreshControl endRefreshing];
});
});
}];
}
Согласно тому, что я прочитал в Apple, документы надлежащим образом, чтобы обнаружить эти изменения на основной нити NSManagedObjectContext заключается в следующем:
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
}
- (void)managedObjectContextDidSave:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue(), ^{
if(notification.object != [[AppManager sharedAppManager] managedObjectContext]) {
[[[AppManager sharedAppManager] managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}
});
}
В принципе, когда я получаю уведомление об изменениях в любом файле managedObjectContext. Я объединяю изменения в контексте основного потока. И он работает вообще, , но после того, как я начал профилирование, я обнаружил, что все объекты, которые объединены в описанный процесс, никогда не освобождаются.
Когда я делаю все на главной теме - он работает - они освобождаются, как ожидалось, при прокрутке UITableView.
Я нашел обходной путь, и я звоню:
[[[AppManager sharedAppManager] managedObjectContext] reset];
После слияния сделано:
[[[AppManager sharedAppManager] managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
[[[AppManager sharedAppManager] managedObjectContext] reset];
Но я понятия не имею, почему я должен это сделать, и если это разобьет что-то остальное. Возможно, есть лучший способ обновить данные в фоновом режиме, и я полностью ошибаюсь.
Ваши «другие вещи» хорошо соблюдены. Но, нужно ли нам частично обрезать граф объектов? Я думаю, что эта «обрезка» относится к освобождению объектов «жизни» без внешней ссылки и, таким образом, освобождению излишне занятой ОЗУ. И оперативная память всегда беспокоит мобильные устройства, поэтому нам нужно _allways_ посылки 'refreshObject: mergeChanges:' для того, чтобы вызвать сбои:/ – CouchDeveloper
Некоторая полезная информация здесь, но обратите внимание, что ваши первые два абзаца ошибочны. У базовых данных абсолютно нет циклов, которые вам нужно знать и ломать. http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/CoreData/Articles/cdMemory.html#//apple_ref/doc/uid/TP40001860-SW3 – memmons
Вам нужно разбить его, только если вы все еще сохраняете эти объекты. Если вы этого не сделаете, Core Data выпустит данные, когда это будет важно, например, при предупреждении о низкой памяти. Если бы правила нормального управления памятью здесь не применимы, то с течением времени память будет расти бесконечно. См. Также комментарий Маркуса Зарры здесь: http://stackoverflow.com/a/3332177/1812858 – eofster