0

我对核心数据和NSManagedObject课程有疑问。我有一个带有实体“ UserProfile”的数据模型,其中包含几个属性,包括“ userId”、“ username”和“ clientId”,这些属性是必不可少的。所有这三个属性在核心数据模型中都被标记为“字符串”。

UserProfile源包含以下内容:

// UserProfile.h
#import <Foundation/Foundation.h>

@interface UserProfile : NSManagedObject

@property (nonatomic, retain) NSString* userId;
@property (nonatomic, retain) NSString* clientId;
@property (nonatomic, retain) NSString* userName;

// simple routine to display essential information about the user in the user table row
- (NSString*) obtainUserInfo;


// UserProfile.m
@implementation UserProfile

@dynamic userId;
@dynamic userName;
@dynamic clientId;

- (NSString*) obtainUserInfo
{
    return [NSString stringWithFormat:@"%@ - %@", [self valueForKey:@"clientId"], [self valueForKey:@"userName"]];
}

当用户用一些文本字段填写表单并按下提交按钮时,我创建了 UserProfile 类的新实例。回调方法中的相关代码块如下:

Q3AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

NSEntityDescription *desc = [NSEntityDescription entityForName:@"UserProfile" inManagedObjectContext:context];

// this line creates the managed object instance and stores it!
UserProfile *newProfile = [[UserProfile alloc]initWithEntity:desc insertIntoManagedObjectContext:context];

// editing properties now causes the object's state to switch to "isChanged". Changes only persist if they're explicitely saved
[newProfile setUserId: [UUIDCreater generateUUID]];
[newProfile setClientId: clientField.text];
[newProfile setUserName: userNameField.text];

NSError *error = nil;
[context save:&error];

if (!error)
{
    // now send the result data to the other controller (via the delegate object)
    [delegate newProfileCreated];


    // dismiss this view
    [self dismissModalViewControllerAnimated:YES];
}
else 
{

    NSLog(@"Error: %@", error);

}

接下来,表格视图控制器从核心数据存储中提取所有用户配置文件,并使用原型单元格显示它们。

好的,到目前为止这一切都有效,但我的问题开始于这个UserProfilesTable类的代码,它是 UserProfile 表视图的 ViewController。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"userProfileEntry";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


// Configure the cell...
UserProfile *obj = [_userProfileList objectAtIndex:indexPath.row];
NSLog(@"ClientId: %@", [obj valueForKey:@"clientId"]);
NSLog(@"UserName: %@", [obj valueForKey:@"userName"]);

// !!CRASH!!
NSLog(@"From Method: %@", [obj obtainUserInfo]);

cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", [obj valueForKey:@"clientId"], [obj valueForKey:@"userName"]];   
return cell;
}

前两个NSLogs 打印我刚刚在表单中输入的正确值以创建新的用户配置文件(因此,崩溃下方的命令也可以按预期工作)。所以.. 使用基本的 KVC,我从 UserProfile 实例中获取了 clientId 和 userName 的值,但是为什么应用程序会因...而崩溃

NSInvalidArgumentException(原因:-[NSManagedObject gainUserInfo]:无法识别的选择器发送到实例 0x6c40b90)[0x6c40b90 在这种情况下是我的 UserProfile 实例]

...如果我尝试从UserProfile做几乎相同的事情的类中访问方法,只是封装到一个单独的方法中以提高可变性和东西?

似乎仅仅因为我子类化NSManagedObject了它就不会让我再访问我的私有类方法了。我在该方法上设置了一个断点obtainUserInfo并且它没有被触发,这对我来说意味着应用程序甚至没有进入该方法。

我发现另一个线程与此问题基本相同,但是threadstarter自己回答并通过重新创建核心数据实体来解决它。我也做了同样的事情,但并没有解决我的问题。

我的提示不多了,所以任何建议都值得赞赏。

提前致谢。

编辑:固定。忘记将我的 UserProfile 类的类名分配给 XCode 的数据模型检查器中的核心数据实体。谢谢你的帮助!

4

2 回答 2

1

原因:-[NSManagedObject gainUserInfo]:无法识别的选择器发送到实例 0x6c40b90

此消息意味着正在接收(但未能处理)obtainUserInfo消息的对象是NSManagedObject.

[0x6c40b90 在这种情况下是我的 UserProfile 实例]

不,不是。它是您的UserProfile 实体的一个实例,但它仍然属于NSManagedObject 该类valueForKey:在这种情况下,被访问的基本属性仍然有效。

这可能意味着您的数据模型没有为 UserProfile 实体指定特定的托管对象子类,因此新实例将作为 NSManagedObjects 返回。

于 2012-07-23T13:25:04.350 回答
1

在我看来,您尚未将实体的自定义子类设置为UserProfile. 您需要在数据模型检查器中设置实体的类。否则NSManagedObject从商店取货时将使用 s。

于 2012-07-23T13:28:54.027 回答