8

我将登录用户的数据从服务器导入一个名为“用户”的核心数据实体。我还将这个特定 User 对象的引用保存到我的 AppDelegate 上(作为一个属性),这样我就可以在我的应用程序的其他地方访问它。我面临的问题是,当我推送另一个视图控制器并尝试访问 appdelegate.loggedInUser.id 时,我看到“id”为 nil。调试器为对象显示了这个:

$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*/
4

2 回答 2

12

我也有同样的问题。事实证明,根据引用Apple 文档的这个答案, an并没有像您预期的那样强烈引用它。我怀疑,如果您在对象未正确触发故障时检查对象,那么.NSManagedObjectNSManagedObjectContext[myObject managedObjectContext] == nil

我不知道这里有什么最佳做法。显而易见(但可能很困难)的解决方案是找出您的 MOC 被释放的原因。作为替代方案,虽然我不确定这样做是否安全,但您可以保留每个NSManagedObject实例的 MOC。(我对这里打开的问题有疑问。)

于 2014-05-15T19:40:30.033 回答
1

确保你不打电话

[managedObjectContext reset];

某处。来自苹果文档:

将接收器返回到其基本状态。所有接收者管理的对象都被“遗忘”了。如果使用此方法,则应确保还丢弃对使用接收器获取的任何托管对象的引用,因为之后它们将无效。

那些“孤立的”托管对象的 managedObjectContext 属性将变为 nil 并且它们将无法再触发故障。

于 2015-02-05T15:36:03.067 回答