Подтвердить что ты не робот

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'

Что взломать неправильно?

4b9b3361

Ответ 1

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

initWithEntity:insertIntoManagedObjectContext:

вместо

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

Подробнее..

Ответ 2

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

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

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

Надеюсь, это поможет, эта нить мне очень помогла!

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

@implementation NSManagedObject(MyPrivateAdditions)

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

@end

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

Challenges *newChallenge = [Challenge insertNewObjectInContext:context];