Core Data不会触发NSManagedObject实例的错误,作为应用程序委托的属性

我将login的用户数据从服务器导入到名为“用户”的核心数据实体中。 我也将这个特定的用户对象引用到我的AppDelegate(作为一个属性),所以我可以在我的应用程序的其他地方访问它。 我面对的问题是,当我推另一个视图控制器,并尝试访问appdelegate.loggedInUser.id,我看到“ID”为零。 debugging器显示这个对象:

$24 = 0x0b28ad30 <User: 0xb28ad30> (entity: User; id: 0xb261160 <x-coredata:///User/tC48E8991-B8A6-4E68-9112-93F9F21DB5382> ; data: <fault>) 

我的理解是,当我尝试访问这个对象的某个属性时,Core Data框架将触发这个错误。 我很困惑,为什么我在这种情况下访问用户的“id”属性没有引发错误?

编辑

这是如何创build和使用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*/ 

我也有同样的问题。 事实certificate,根据这个引用Apple文档的 回答 , NSManagedObject并不像您期望的那样持有对其NSManagedObjectContext的强引用。 我怀疑,如果你检查你的对象,当它不正确地触发错误[myObject managedObjectContext] == nil

我不知道最佳做法在这里。 明显的(但可能是困难的)解决scheme是找出你的MOC被释放的原因。 另外, 尽pipe我不确定是否安全 ,但是可以保留每个NSManagedObject实例的MOC。 (我对此有疑问。)

确保你不打电话

 [managedObjectContext reset]; 

某处。 来自Apple文档:

将接收器返回到其基本状态。 所有接收者的被pipe理对象都被“遗忘”了。如果你使用这个方法,你应该确保你也放弃了对使用接收者获取的任何被pipe理对象的引用,因为之后它们将是无效的。

那些“孤立”的托pipe对象的managedObjectContext属性将变为零,他们将无法再触发故障。

在返回newUserEntity的值之前,在你的代码中保存“save”时,你应该调用保存在你的localContext上:

 + (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; } 

我希望这将有所帮助。