Некоторые отношения CoreData теряются после закрытия приложения - PullRequest
8 голосов
/ 21 декабря 2011

Это обзор моей проблемы:

Я добавляю (и подтверждаю, что они добавлены) около 1400 отношений, загруженных из службы мыла в CoreDat. После того, как я закрываю приложение и открываю его снова, некоторые отношения теряются; Я вижу только около 800 из них (хотя это варьируется). Также я не получаю никаких ошибок.

А теперь подробнее:

У меня есть объект с именем User, который содержит информацию об услугах, которые пользователь сохранил; это выглядит примерно так:

@interface OosUser : NSManagedObject

    + (OosUser *) userFromSlug: (NSString *) slug;
    @property (nonatomic, retain) NSString *name;
    @property (nonatomic, retain) NSString *slug;
    @property (nonatomic, retain) NSMutableSet /* Service */ *services;
    - (void) addServicesObject: (Service * )service;
    - (void) removeServicesObject: (Service *) service;

@end

@implementation User

   @dynamic name;
   @dynamic slug;
   @dynamic services;

   static NSString *fetchPredicate = @"slug = %@";

   + (User *) userFromSlug:(NSString *)slug
   {
       User *result = [super objectWithPredicate: fetchPredicate, slug];
       if (!result) {
           result = [super create];
           result.slug = slug;
       }
   return result;
   }

@end

В той части кода, где используются данные, отношения сохраняются следующим образом:

NSMutableSet *userServices = self.user.services;

for (Service *service in servicesToAdd) {
        [self.services addObject: service];
        bool contained = false;
        for (Service *userService in userServices) {
            if ((contained = [userService.slug isEqualToString:service.slug])) {
                break;
            }
        }
        if (!contained) {
            // [userServices addObject:service];
            [self.user addServicesObject: service];
            NSError *error = nil;
            if (![[service managedObjectContext] save:&error]) {
                NSLog(@"Saving failed");
                NSLog(@"Error: %@", [error localizedDescription]);
            }else {
                NSLog(@"Registered service %d: %@", self.services.count, service.slug);
            }
        }
    }

Дело в том, что я проверил с помощью отладчика, и я вижу, что добавлены все более 1400 отношений, но когда приложение сбрасывается и восстанавливается, хотя self.user.services, я получаю только около 800 объектов.

Почему это могло происходить? Кто-нибудь имел это раньше?

Заранее спасибо.


UPDATE:

Люди продолжают утверждать, что я не правильно использую Core Data, но проблема в том, что данные теряются ПОСЛЕ перезапуска приложения. Там нет абсолютно никаких проблем с ним при использовании. Я использую Базовые данные настолько корректно, насколько это возможно, учитывая ограниченную документацию и примеры, которые вы получаете от Apple.

Ответы [ 6 ]

11 голосов
/ 21 декабря 2011
NSMutableSet *userServices = self.user.services;

...

            [userServices addObject:service];

Не могу этого сделать.self.user.services не возвращает изменяемый набор.Вот для чего этот метод addServicesObject.Измените вторую строку на:

            [self.user addServicesObject:service];

Из документации Apple:

Важно понимать разницу между значениями, возвращаемыми аксессором точки, и mutableSetValueForKey:.mutableSetValueForKey: возвращает изменяемый прокси-объект.Если вы изменяете его содержимое, оно отправляет соответствующие уведомления об изменении значения ключа (KVO) для взаимосвязи.Точечный метод доступа просто возвращает набор.Если вы управляете набором, как показано в этом фрагменте кода:

[aDepartment.employees addObject:newEmployee]; // do not do this! then KVO change notifications are not emitted and the inverse relationship is not updated correctly.

Напомним, что точка просто вызывает метод доступа, поэтому по тем же причинам:

[[aDepartment employees] addObject:newEmployee]; // do not do this, either!

4 голосов
/ 21 декабря 2011

У меня та же проблема, но после настройки обратных отношений все снова в порядке.Надеюсь, это поможет разобраться с этой проблемой.

1 голос
/ 29 декабря 2011

Хорошо, давайте посмотрим на симптомы здесь.Вы вносите изменения в объекты внутри контекста, но при перезапуске приложения некоторые, но не все эти изменения присутствуют.

Это может означать только то, что эти изменения не записываются в постоянное хранилище.Поскольку вы видите некоторые из изменений, вы вызываете метод save:, но Core Data не распознает все объекты как требующие сохранения.

Это приводит нас к тому, как вы выполняете изменения вуказанные объекты.Вы вносите изменения в соответствии с требованиями KVO?Базовые данные опираются на KVO, чтобы знать, какие изменения произошли, и, следовательно, какие изменения необходимо сохранить.Если вы изменяете объекты не-KVO-способом, они будут казаться измененными, когда вы их исследуете, но Базовые данные не будут знать, что эти изменения существуют, и поэтому не будут знать, что они должны их сохранять.* Я бы изменил ваш код следующим образом, при условии, что объект Service имеет обратную зависимость обратно к User (и это отношение называется user, и является частью 1-M):

[servicesToAdd setValue:self.user forKey:@"user"];

NSError *error = nil;
if (![[service managedObjectContext] save:&error]) {
    NSLog(@"Saving failed");
    NSLog(@"Error: %@", [error localizedDescription]);
}

Это зависит от того факта, что Базовые данные позаботятся об обоих концах отношений для вас, где установлены обратные отношения.Конечно, если это отношение «многие ко многим», то код немного отличается, но мы по-прежнему используем KVO-совместимые методы для внесения изменений.

[servicesToAdd setValue:self.user forKey:@"user"];

for (Service *service in servicesToAdd) {
    [user addServicesObject:service];
} 

NSError *error = nil;
if (![[service managedObjectContext] save:&error]) {
    NSLog(@"Saving failed");
    NSLog(@"Error: %@", [error localizedDescription]);
}
0 голосов
/ 28 ноября 2016

Для меня проблема заключалась в обратной зависимости

Есть моя модель

enter image description here

Все, что нужно для включения обратной связикак это:

enter image description here

enter image description here

0 голосов
/ 04 декабря 2013

У меня возникала та же проблема: связь с другим объектом терялась при каждом перезапуске приложения.Я искал часами.В конце концов я нашел проблему.Я объявил мои отношения как Transient, это вызвало проблему.

enter image description here

0 голосов
/ 21 декабря 2011

В конце концов, я решил это с помощью пользовательского NSPredicate, который выбирает службы, используя один специальный параметр, который я устанавливаю для служб, когда они добавляются пользователем.

Это работает, хотя и не идеально.

...