39

我对 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 init 之后,我得到了这个错误:

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

黑客出了什么问题?

4

5 回答 5

60

我认为问题在于 Challenges 是一个NSManagedObject类,您需要指定的初始化程序:

initWithEntity:insertIntoManagedObjectContext:

代替

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

阅读更多..

于 2013-02-03T10:34:39.187 回答
30

如果您问自己“好的,那么我如何获得该实体?” (就像我所做的那样),您可以使用 entityForName 方法来执行此操作,如下所示:

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

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

希望这会有所帮助,这个帖子对我有很大帮助!

于 2013-06-13T01:16:58.810 回答
14

NSManagedObject不能只是alloc/init就像你通常用NSObject. 事实上,指定的初始化程序是: initWithEntity:insertIntoManagedObjectContext:

现在,对于实际错误,Apple在文档中声明:

重要提示:此方法是 NSManagedObject 的指定初始化程序。您不能简单地通过发送 init 来初始化托管对象。

所以,你可以看到你需要两件事来初始化它,一个NSEntityDescription(你打算实例化的实体)和一个NSManagedObjectContext(新对象将被创建到的上下文)。

于 2013-02-03T10:36:20.577 回答
4

另外,如果您的 Challenges 类是 NSManagedObject 并且 date、rounds 和 shot 被定义为它的属性,您可以添加方法:

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

每个新对象从一出生就定义了这些属性。

于 2013-02-03T12:35:19.713 回答
4

其他人已经说明了为什么它不起作用。以下是您可以减少样板文件并使代码更具可读性的方法:

@implementation NSManagedObject(MyPrivateAdditions)

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

@end

现在你可以这样做:

Challenges *newChallenge = [Challenge insertNewObjectInContext:context];
于 2013-08-14T00:58:29.807 回答