为什么Core Data失去了我的一个价值观?

时间:2011-08-15 10:46:58

标签: objective-c ios core-data

在我的用户对象中,我有以下代码来生成新的“会话”或继续现有会话(如果存在)。

奇怪的是,它会保留其他属性,但只是失去了'user'属性...用户与会话有一对多的关系,1个用户可以拥有多个会话。 (或将会做,对于以下测试,我只是检查以前的任何会话并使用它(如果存在)

-(void)setupSessionStuff
{
// Create new Core Data request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];

// Create Sort Descriptors for request
NSSortDescriptor *startTimeSort = [[NSSortDescriptor alloc] initWithKey:@"startTime" ascending:NO selector:nil];
[request setSortDescriptors:[NSArray arrayWithObjects:startTimeSort, nil]];
[startTimeSort release];

[request setFetchLimit:1]; // Only get the most recent session

// Execute request
NSError *error = nil;
NSArray *results = [[self managedObjectContext] executeFetchRequest:request error:&error];
if (results == nil) {
    // Something went horribly wrong...
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    exit(-1);
}
[request release];

Session *theSession = nil;

if ([results count] == 1) {
    NSLog(@"existing session");
    // Use existing Session
    theSession = [results objectAtIndex:0];

    NSLog(@"session.user: %@", [theSession valueForKey:@"user"]); // this is always null!

} else {
    NSLog(@"new session");
    // Create new Sesson
    theSession = (Session *)[NSEntityDescription insertNewObjectForEntityForName:@"Session" inManagedObjectContext:[self managedObjectContext]];

    // Add the Session to the User
    NSLog(@"before: session.user: %@", theSession.user); // null
    theSession.user = self;
    NSLog(@"after: session.user: %@", theSession.user); // looks good
}

...


NSLog(@"before.save: session.user: %@", theSession.user); // good

// Save everything
error = nil;
if (![[self managedObjectContext] save:&error]) {
    // Something went horribly wrong...
    NSLog(@"Unresolved error: %@, %@, %@", error, [error userInfo],[error localizedDescription]);
    exit(-1);
}

NSLog(@"after.save: session.user: %@", theSession.user); // still there..
}

此外,我已打开Core Data sqlite文件并使用SQLite Manager进行检查。 看起来就像关系已正确保存一样,因为我可以看到存储在会话表中的userID。

-

刚刚在我的方法开头添加了这个作为另一个测试。

NSSet *set = self.session;

for(Session *sess in set) {
    NSLog(@"startTime %@", sess.startTime);
    NSLog(@"user %@", sess.user);

}

奇怪的是,在这种情况下用户设置了!?所以在这里设置然后在我执行获取请求时不设置几行......?

-

回应以下反馈

在分配session.user = self后添加了此代码,并且都返回了预期的输出。所以看起来问题就在于随后的提取。

NSLog(@"self.session: %@", self.session);
NSLog(@"self.session: %@", [self valueForKey:@"session"]);

此外,我同意通过self.session访问我的会话将让我解决我的问题,但它不能解决这里发生的事情。 在其他地方,我肯定无法从一个实体走到另一个实体,所以需要相信获取将正确地提取所有内容。

2 个答案:

答案 0 :(得分:0)

首先,我会通过记录self.session检查关系是否从另一方设置。如果显示为null,则表示模型中没有设置相互关系。

我认为你的获取结构很差。您依靠排序描述符来提供上次使用的会话,但您只有1的获取限制。您似乎认为fetch将找到所有现有的Session对象,对它们进行排序然后返回第一个。但是,排序最后执行,因此获取将找到单个会话对象(由于获取限制),然后将排序应用于该单个对象。这使得您可能会处理或多或少的随机Session对象。

您可能根本不需要提取,因为您只对与Session对象User的关系中的self对象感兴趣。如果你已经将对象放在关系的一边,你不需要取,你只需要走这段关系。你真正需要做的就是:

if ([self.session count]==0){
  //...create new session and set relationship
}else{
  //... find latest session
}

我认为这个特定代码块的问题在于报告。获得返回值后,使用self.user表示法但在null返回的位置使用valueForKey:

虽然理论上两者都返回相同的值,但它们没有必要,因为它们不使用相同的机制来返回值。自点符号调用访问器方法,而valueForKey:可能会或可能不会,这取决于类实现的细节。我会测试self.session是否返回valueForKey:没有的值。

答案 1 :(得分:0)

我找到问题并解决了我的问题...

在检查了我的会话实体的内存地址后,我注意到它在运行之间发生了变化。进一步调查我发现我之前在另一个类中测试了一些代码的地方,创建了一个新的会话实体,但没有保存它,好吧,它毕竟被保存了 - 当我发出保存时我上面的代码!