在我的用户对象中,我有以下代码来生成新的“会话”或继续现有会话(如果存在)。
奇怪的是,它会保留其他属性,但只是失去了'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访问我的会话将让我解决我的问题,但它不能解决这里发生的事情。 在其他地方,我肯定无法从一个实体走到另一个实体,所以需要相信获取将正确地提取所有内容。
答案 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)
我找到问题并解决了我的问题...
在检查了我的会话实体的内存地址后,我注意到它在运行之间发生了变化。进一步调查我发现我之前在另一个类中测试了一些代码的地方,创建了一个新的会话实体,但没有保存它,好吧,它毕竟被保存了 - 当我发出保存时我上面的代码!