NSManagedObjectDidSaveNotification не работает - PullRequest
0 голосов
/ 22 апреля 2011

Я пишу простое приложение OS X с основными данными, и у меня возникла проблема с многопоточными данными ядра.Проблема в том, что я хочу изменить логическое значение в фоновом потоке, но когда я сохраняю, значение возвращается к старому значению.Я также изменяю строковое значение в том же потоке, и оно отлично работает.

Вот мой код (немного упрощенный)

@implementation UpdateOperation
...
- (void)main {
    @try {
        NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
        [context setPersistentStoreCoordinator:[delegate persistentStoreCoordinator]];

        // Register context with the notification center
        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
        [nc addObserver:self
               selector:@selector(mergeChanges:)
                   name:NSManagedObjectContextDidSaveNotification
                 object:context];

        NSArrayController *siteArrayController = [[NSArrayController alloc] init];
        [siteArrayController setManagedObjectContext:context];
        [siteArrayController setEntityName:@"Page"];
        [siteArrayController fetchWithRequest:nil merge:YES error:NULL];

        ...

        [[[siteArrayController arrangedObjects] objectAtIndex:0] setValue:[NSNumber numberWithBool:YES] forKey:@"updated"];
        [[[siteArrayController arrangedObjects] objectAtIndex:0] setValue:newMD5 forKey:@"oldMD5"];

        NSLog(@"[context updatedObjects] before saving: %@", [context updatedObjects]);
        NSLog(@"Object 0 before saving: %@", [[siteArrayController arrangedObjects] objectAtIndex:0]);

        NSError *error;
        BOOL saveSucceeded = [context save:&error];
        NSLog(@"saveSucceeded: %@", (saveSucceeded ? @"YES" : @"NO"));
        NSLog(@"error: %@", error);

        NSLog(@"Object 0 after saving: %@", [[siteArrayController arrangedObjects] objectAtIndex:0]);

    }
    @catch (NSException *exception) {

    }
}

- (void)mergeChanges:(NSNotification *)notification
{
    NSManagedObjectContext *mainContext = [delegate managedObjectContext];
    NSLog(@"Notification updated objects: %@", [[notification userInfo] objectForKey:NSUpdatedObjectsKey]);
    // Merge changes into the main context on the main thread
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:notification
                               waitUntilDone:YES];  
}

@end

Вывод выглядит так:

[context updatedObjects] before saving: {(
    <NSManagedObject: 0x2000aacc0> (entity: Page; id: 0x200025ce0 <x-coredata://77B4A16E-0BE3-4D2F-8026-C11CBC35C609/Page/p102> ; data: {
    address = "http://stackoverflow.com";
    name = Stackoverflow;
    oldMD5 = cd32dbfb6fc3f7cca09f45ee811cab0;
    updated = 1;
})
)}

Object 0 before saving: <NSManagedObject: 0x2000aacc0> (entity: Page; id: 0x200025ce0 <x-coredata://77B4A16E-0BE3-4D2F-8026-C11CBC35C609/Page/p102> ; data: {
    address = "http://stackoverflow.com";
    name = Stackoverflow;
    oldMD5 = cd32dbfb6fc3f7cca09f45ee811cab0;
    updated = 1;
})

Notification updated objects: {(
    <NSManagedObject: 0x2000aacc0> (entity: Page; id: 0x200025ce0 <x-coredata://77B4A16E-0BE3-4D2F-8026-C11CBC35C609/Page/p102> ; data: {
    address = "http://stackoverflow.com";
    name = Stackoverflow;
    oldMD5 = cd32dbfb6fc3f7cca09f45ee811cab0;
    updated = 0;
})
)}

saveSucceeded: YES
error: (null)  

Object 0 after saving: <NSManagedObject: 0x2000aacc0> (entity: Page; id: 0x200025ce0 <x-coredata://77B4A16E-0BE3-4D2F-8026-C11CBC35C609/Page/p102> ; data: {
    address = "http://stackoverflow.com";
    name = Stackoverflow;
    oldMD5 = cd32dbfb6fc3f7cca09f45ee811cab0;
    updated = 0;
})

Таким образом, обновленное значение теряется во время сохранения.Тем не менее, значение oldMD5 работает отлично.Кто-нибудь понял, что я здесь делаю не так?

Ответы [ 2 ]

0 голосов
/ 23 апреля 2011

Проблема решена, возможно, это ошибка XCode или что-то в этом роде.По сути, я создал новый атрибут с такими же параметрами и изменил код, чтобы использовать его вместо обновленного атрибута.Теперь все работает.Несмотря на то, что опция Transient в обновлении не была проверена, я думаю, что она все еще была временной, XCode просто не изменил ее.

0 голосов
/ 22 апреля 2011

Во-первых, вы зарегистрировали фоновый поток, чтобы получать уведомления о его собственных изменениях. Это бессмысленно. Вам необходимо зарегистрировать контекст переднего плана для получения уведомлений об изменениях в фоновом контексте, потому что вам нужно объединить два контекста.

Во-вторых, я подозреваю, что ваше сохранение в фоновом контексте не удается, но, поскольку вы не перехватываете ошибку, вы не можете ее увидеть. Исключения работают в Objective-C / Apple-API иначе, чем в Java, C ++ или C #. В цели C исключения касаются непредвиденных проблем. Поскольку неудачное сохранение всегда является ожидаемой возможностью, операция сохранения не будет генерировать исключение, если оно произойдет, а просто сообщит об ошибке.

Перехватите и зарегистрируйте ошибку, и она скажет вам, почему сохранение не удалось.

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