我将登录用户的数据从服务器导入名为“User”的核心数据实体。我还将这个特定用户对象的引用保存到我的AppDelegate(作为属性),以便我可以在我的应用程序的其他位置访问它。我面临的问题是,当我推送另一个视图控制器并尝试访问appdelegate.loggedInUser.id时,我看到“id”为零。调试器为对象显示:
$24 = 0x0b28ad30 <User: 0xb28ad30> (entity: User; id: 0xb261160 <x-coredata:///User/tC48E8991-B8A6-4E68-9112-93F9F21DB5382> ; data: <fault>)
我的理解是,当我尝试访问此对象的某个属性时,Core Data框架会触发错误。我很困惑为什么我在这种情况下访问用户的“id”属性没有触发错误?
修改:
这是创建和使用loggedInUser对象的方法:
//method to get bgContext
+(NSManagedObjectContext *)getContextOnBgWithParentSetToMainMOC
{
NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[tmpContext setParentContext:[Utils getAppDelegate].managedObjectContext];
return tmpContext;
}
//in App Delegate
NSManagedObjectContext *bgContext = [NSManagedObjectContext getContextOnBgWithParentSetToMainMOC];
self.loggedInUser = [User importFromObject:loggedInUserData inContext:bgContext completionBlock:^(NSManagedObjectContext *theContext, NSManagedObject *theManagedObjectWithValuesImported) {}];
//In User.m file
+ (User *)importFromObject:(NSDictionary *)dictionary inContext:(NSManagedObjectContext *)context completionBlock:(TemporaryContextImportReturnBlock)block {
if ( !context ){
context = [NSManagedObjectContext getContextOnBgWithParentSetToMainMOC];
}
NSManagedObjectContext *localContext = context;
User *newUserEntity = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:localContext];
NSArray *emailsArray = [dictionary objectForKey:@"emails"];
NSString *emailsString = @"";
if ([emailsArray count] > 0){
emailsString = [emailsArray componentsJoinedByString:@","];
}
newUserEntity.emails = emailsString;
newUserEntity.id = [dictionary objectForKey:@"id"];
newUserEntity.n = [dictionary nonNullObjectForKey:@"n"];
return newUserEntity;
}
//Access in one of the view controllers
User *loggedInUser = [Utils getAppDelegate].loggedInUser;
// loggedInUser.id /*nil*/
答案 0 :(得分:8)
我有同样的问题。根据引用this answer的Apple docs,NSManagedObject
NSManagedObjectContext
可能会期待。我怀疑如果你检查对象时它没有正确地发出[myObject managedObjectContext] == nil
。
我不知道这里有什么最佳做法。显而易见(但可能很困难)的解决方案是找出您的MOC被解除分配的原因。作为替代方案,虽然我不确定是否可以安全地执行,但您可以保留每个NSManagedObject
实例的MOC。 (我对此问题有疑问here。)
答案 1 :(得分:0)
确保您没有打电话
[managedObjectContext reset];
某处。来自Apple doc:
将接收器返回到其基本状态。 所有接收者的托管对象都被“遗忘”。如果您使用此方法,您应该确保您也放弃对使用接收器获取的任何托管对象的引用,因为它们之后将无效。
那些“孤立”托管对象的managedObjectContext属性将更改为nil,并且它们将无法再触发故障。
答案 2 :(得分:-1)
在您的代码中,在返回newUserEntity的值之前,“save”缺失,您应该在localContext上调用save:
+ (User *)importFromObject:(NSDictionary *)dictionary inContext:(NSManagedObjectContext *)context completionBlock:(TemporaryContextImportReturnBlock)block {
if ( !context ){
context = [NSManagedObjectContext getContextOnBgWithParentSetToMainMOC];
}
NSManagedObjectContext *localContext = context;
User *newUserEntity = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:localContext];
NSArray *emailsArray = [dictionary objectForKey:@"emails"];
NSString *emailsString = @"";
if ([emailsArray count] > 0){
emailsString = [emailsArray componentsJoinedByString:@","];
}
newUserEntity.emails = emailsString;
newUserEntity.id = [dictionary objectForKey:@"id"];
newUserEntity.n = [dictionary nonNullObjectForKey:@"n"];
NSError *error = nil;
[localContext save:&error];
if(error) {
NSLog(@"error %@", error);
}
return newUserEntity;
}
我希望这会有所帮助。