Core Data 实体在方法中返回后缺少其属性

Posted

技术标签:

【中文标题】Core Data 实体在方法中返回后缺少其属性【英文标题】:Core Data entity lacks its attributes after being returned in a method 【发布时间】:2013-04-05 14:55:01 【问题描述】:

我遇到了一个问题,我有一个方法应该返回从当前线程的上下文中获取的 Core Data 实体对象。

当我在调试模式下编译和运行项目时,一切正常,但是当应用程序以 RELEASE 运行时,会出现奇怪的行为。返回的对象缺少其属性(它们是 nil 或 0)。应用程序正在使用 ARC 来管理内存。

该实现使用 NSManagedObject 上的一个类别,方法如下:

- (id)threadLocalSelf 
    return [self selfInContext:[NSManagedObjectContext threadLocalContext]];


- (id)selfInContext:(NSManagedObjectContext *)context 
    NSAssert(context, @"context cannot be nil!");
    if(context == self.managedObjectContext)
        return self;

    NSManagedObjectID *objectID = [self objectID];
    if([objectID isTemporaryID])
        [NSException raise:NSInternalInconsistencyException format:@"objectID cannot be temporary when fetching self in another context!"];

    NSError *error = nil;
    NSManagedObject *_self = [context existingObjectWithID:objectID error:&error];
    if(error)
        [NSException raise:NSInternalInconsistencyException format:@"Failed to fetch self: %@ in context: %@, error: %@", objectID, context, error];

    NSAssert(_self, @"context: %@ does not contain an object with objectID: %@", context, objectID);

    NSLog(@"Returning _self: %@", _self);

    return _self;

[NSManaged threadLocalContext] 为当前线程创建一个新的 NSManagedObjectContext。

这里的问题是,当 NSLogging 退出即将返回的对象时,一切似乎都很好。有关实体的所有属性和信息都是正确的。

但是 - 在对象返回后注销对象时(如下所示),所有属性均为 nil 或 0。此行为仅在 RELEASE 中发生,而不在 DEBUG 中发生。

Foo * bar = [baz threadLocalSelf];
NSLog(@"Foo object: %@", bar); 

上面的代码导致对象被正确地从方法中注销,但紧随其后的 NSLog 具有空属性。虽然 ObjectID 在这两种情况下都是正确的,并且对象本身不是 nil。

关于可能导致此问题的任何想法都非常受欢迎。

【问题讨论】:

【参考方案1】:

您的线程新上下文在分配和使用后将被释放。

- (id)threadLocalSelf 
    return [self selfInContext:[NSManagedObjectContext threadLocalContext]/*released at the end of method*/];

【讨论】:

谢谢!你刚刚拯救了我的一天。 没问题,很高兴为您提供帮助:)【参考方案2】:

您仅在发布版本中看到此行为的原因是,NSManagedObjectContext 在调试版本中被放入自动释放池中,但 ARC 优化器在发布版本中立即释放它。您可以通过立即耗尽自动释放池来在您的调试版本中复制它:

- (id)threadLocalSelf 
    @autoreleasepool 
        return [self selfInContext:[NSManagedObjectContext threadLocalContext]];
    

【讨论】:

感谢您解释 DEBUG/RELEASE 的区别!

以上是关于Core Data 实体在方法中返回后缺少其属性的主要内容,如果未能解决你的问题,请参考以下文章

Core Data Fetch 没有返回它应该返回的对象

在 Core Data 中为实体添加属性

如何将实体上的属性迁移到 Core Data 中的实体

Core Data 中父实体的计算属性

在 Core Data 可转换字符串数组上返回匹配项的 Swift 谓词

iOS开发学习之Core Data