CoreData: ошибка: не удалось вызвать назначенный инициализатор в классе NSManagedObject

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

Challenges *newChallenge = [[Challenges alloc] init];
[newChallenge setName:@"TestChallenge"];
[newChallenge setRounds:[[NSNumber alloc] initWithInt:12]];
[newChallenge setShots:[[NSNumber alloc] initWithInt:5]];
[newChallenge setDate:[NSDate date]];

но однако после инициализации alloc я получаю эту ошибку:

CoreData: error: Failed to call designated initializer on NSManagedObject class 'Challenges'

что Хак идет не так?

5 ответов


Я думаю, проблема в том, что вызовы-это NSManagedObject class и вам нужен назначенный инициализатор:

initWithEntity:insertIntoManagedObjectContext:

вместо

Challenges *newChallenge = [[Challenges alloc] init];

Подробнее..


в случае, если вы спросите себя: "хорошо, так как мне получить эту сущность?"(как и я), вы делаете это, используя метод entityForName следующим образом:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Challenges" inManagedObjectContext:self.managedObjectContext];

Challenges *newChallenge = [[Challenge alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];

надеюсь, это поможет, этот поток помог мне много!


NSManagedObject нельзя просто alloc/init Как вы обычно делаете с NSObject. На самом деле назначенный инициализатор: initWithEntity:insertIntoManagedObjectContext:

теперь, для фактической ошибки, Apple состояния в документации что:

важно: этот метод является назначенным инициализатором для NSManagedObject. Нельзя инициализировать управляемый объект просто отправив его инициализации.

Итак, вы могли видеть что вам нужно 2 вещи, чтобы инициализировать его,NSEntityDescription (какой объект вы собираетесь создать) и NSManagedObjectContext (контекст, в который будет создан новый объект).


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

@implementation NSManagedObject(MyPrivateAdditions)

+ (id)insertNewObjectInContext:(NSManagedObjectContext *)context
{
    return [NSEntityDescription insertNewObjectForEntityForName:self.className inManagedObjectContext:context];
}

@end

теперь вы можете сделать:

Challenges *newChallenge = [Challenge insertNewObjectInContext:context];

дополнительно, если ваш класс Challenges - NSManagedObject и date, раунды и выстрелы определяются как его атрибуты, вы можете добавить метод:

-(void) awakeFromInsert {
     self.date = [NSDate date];
     self.rounds = @(12);
     self.shots = @(5);
}

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