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 实体在方法中返回后缺少其属性的主要内容,如果未能解决你的问题,请参考以下文章