сохранение NSManagedObjectContext заставляет приложение ждать бесконечно - PullRequest
0 голосов
/ 28 июля 2011

Почему каждый раз, когда я вызываю save в моем NSManagedObjectContext:

-(NSManagedObjectContext*)managedObjectContext {
    NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
    NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
    if (!backgroundThreadContext) {
        backgroundThreadContext = [self newManagedObjectContext];
        [threadDictionary setObject:backgroundThreadContext forKey:RKManagedObjectStoreThreadDictionaryContextKey];
        [backgroundThreadContext release];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(mergeChanges:)
                                                     name:NSManagedObjectContextDidSaveNotification
                                                   object:backgroundThreadContext];
    }
    return backgroundThreadContext;
}

- (NSError*)save {
    NSManagedObjectContext* moc = [self managedObjectContext];
    NSError *error = nil;

    @try {
        if (![moc save:&error]) { //breakpoint in here

    //some code
}

приложение, кажется, ждет вечно и никогда не возвращается, чтобы возобновить свое выполнение? Вот что я имею в виду в видео . Может ли это быть вызвано тем, что что-то не так с моделью сущности / отношения?

Вот скриншот инструментов утечки, я не вижу утечек, но кажется, что приложение выделяет что-то, что накапливается:

enter image description here

1 Ответ

0 голосов
/ 28 июля 2011

Вы пробовали отказаться от своего многопоточного кода, чтобы посмотреть, работает ли он?Я предполагаю, что вы смешиваете потоки здесь и получаете доступ к MOC / сохраняете их из разных потоков.Управление потоками вручную - это PITA, попробуйте переключиться на Grand Central Dispatch .

Я бы также дал вашему главному MOC собственный аксессор, чтобы вы могли убедиться, что он не вызывается из фоновых потоков, и есть несколько методов: - (NSManagedObjectContext*)newBackgroundMOC; и - (void)saveBackgroundMOC:(NSManagedObjectContext*)context; для быстрого создания и сохранения MOC из фонаочереди / потоки:

dispatch_async(my_queue, ^{
    NSManagedObjectContext *context = [self newBackgroundMOC]; // create context, setup didSave notification to merge with main MOC, etc

    // modify context

    [self saveBackgroundMOC:context]; // main MOC gets updated
});

Миграция на GCD - это немного работы, но в долгосрочной перспективе вы увидите, что работать с ней гораздо приятнее.Само собой разумеется, что это также самый современный и рекомендуемый Apple способ работы с потоками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...