CoreData问题: - [NSManagedObject setValue:]:发送到实例的无法识别的选择器

时间:2010-12-28 13:35:59

标签: iphone objective-c core-data ios nsmanagedobject

我昨天刚开始使用CoreData,我疯了:(我创建了一个使用CoreData的项目(勾选方框 - 使用CoreData)。创建实体,然后为所有实体创建NSManagedObject类(I假设他们为实体创建了“setter”和“getter”方法。

现在,我在AppDeletegate中#imported了所有这些类,并在我的applicationDidFinishLaunching方法中写了这个:

(订阅是申请中的实体之一)

NSManagedObjectContext *context = [self managedObjectContext];
 Subscriptions *sbs = (Subscriptions *)[NSEntityDescription insertNewObjectForEntityForName:@"Subscriptions" inManagedObjectContext:context];
 [sbs setTitle:@"OK"];
 [sbs setType:@"Tag"];
 [sbs setCode:@"cars"];

 NSError *error = nil;
 if (![context save:&error]) {
  NSLog(@"Couldn't create the subscription");
 }

当我运行时,我收到此错误

  

[NSManagedObject setTitle:]:无法识别的选择器发送到实例0x6160550

我不知道为什么会这样。请帮忙!!! 提前感谢大家!

添加订阅标题
Subscriptions.h

  

@interface订阅:NSManagedObject {
  }
  @property(非原子,保留)NSString *类型;
  @property(非原子,保留)NSDecimalNumber *读;
  @property(非原子,保留)NSString *标题;
  @property(非原子,保留)NSString *代码;
  @property(非原子,保留)NSDecimalNumber *新;
  @end

我没有改变任何事情。就像Xcode创建它一样。

8 个答案:

答案 0 :(得分:32)

提醒一下,不要使用大写变量名,否则可能会影响getter和setter无法正常工作。

如果从数据模型生成NSManagedObject子类,一切都应该没问题,虽然它是@dynamic,setter是由coredata实现的,并且因为它们已经实现,所以不应该将它更改为合成。 至少对我来说,在将@dynamic更改为@synthesize之后,coredata返回空对象。

不要忘记在数据模型中设置类名:

enter image description here

答案 1 :(得分:12)

我得到了这个,并对项目进行了清理并修复了它。

答案 2 :(得分:4)

我向核心数据实体添加了一个响应,而不是重新创建NSManagedObjectSubclass,我试图想象并手动将@property和@dynamic添加到现有的子类。

那个没有用的,所以我通过XCode重新创建了子类,这是我开始收到此错误时("无法识别的选择器发送到实例&#34) ;为属性设置值时。)

所以我通过XCode 创建了新版本的核心数据模型,然后清理,删除了派生数据,然后重新创建了NSManagedObject子类。这很有用。

它可能正在创建一个新的数据模型和基于它的新子类,所以我可能不需要清理或删除派生数据......但它也没有受到伤害!

答案 3 :(得分:3)

两个可能的问题

在.m文件中是否有相应的@dynamic块用于这些属性和

不要使用大写属性,编码约定是至少第一个字母的属性是小写的,这样当编译器合成方法时。

.h中的

@property (nonatomic, retain) NSString * type;

.m

中的

@dynamic type;

变得类似

-(void)setType:(NSString *)atype
{
....
[self willChangeValueForKey:@"type"];
[self setPrimitiveValue:atype forKey:@"type"];
[self didChangeValueForKey:@"type"];
} 

-(NSString *)type
{
return [self primitiveValueForKey:@"type"];
}

在后台。虽然你无法看到那段代码。

案例约定取决于您,但Camel Caps在Cocoa名义上是正常的。但它很像Big Furry Cat这样的对象变成了bigFurryCat。遵循苹果示例中的风格。

编辑 - 将@synthesize更改为@dynamic

答案 4 :(得分:2)

我发现通过与实体建立关系,我必须确保我的一些关系是多对的,我拍了一个屏幕截图,这样你就可以看到我的意思了,双端箭头表示了多对多的关系

enter image description here

答案 5 :(得分:0)

在我看来,Title属性可能不会设置为字符串。你检查一下吗?

通常,发送到实例的无法识别的选择器是一个运行时错误原因,它通过向对象发送消息来告知对象不知道如何处理。

Subscriptions *sbs = (Subscriptions *)[NSEntityDescription insertNewObjectForEntityForName:@"Subscriptions" inManagedObjectContext:context];
sbs.Title = @"OK";

希望有帮助

I made simple project here.

答案 6 :(得分:0)

我遇到了同样的问题,我找到了一个不那么优雅的解决方案。似乎

[NSEntityDescription insertNewObjectForEntityForName:@"myEntity" inManagedObjectContext:myManagedObjectContext];

创建一个旧版本的myEntity,它没有最新版本的属性。所以我将旧版本模型中myEntity的名称更改为myEntityOld,我没有再收到错误。

我怀疑通过设置NSManagedObjectNSEntityDescription的属性,可以在XCode中执行相同的操作。

答案 7 :(得分:0)

采取以下步骤

1)通过Xcode创建了新版本的核心数据模型。

2)修复关系(在两者之间增加了新的关系。 )

Creating Managed Object Relationships

3)重新创建NSManagedObject子类