【问题标题】:NSManagedObject crashing on NSOperation (ARC)NSManagedObject 在 NSOperation (ARC) 上崩溃
【发布时间】:2013-02-25 23:44:42
【问题描述】:

我正在将我的项目转换为 ARC,当我到达一些负责在后台下载一些图像的 NSOperation 子类时,代码开始崩溃。

所以我有我的NSOperation 子类及其主要代码:

- (void)main
{
    Post *p = [[Post alloc] initWithNewManagedObjectContext];
    Post *post = (Post *)[p findById:postId];
    [post downloadAndProcessImageOfTypeThumbOrAll:thumbOrAll];

    if (![self isCancelled]) {
        [target performSelectorOnMainThread:afterCompletionAction withObject:postId waitUntilDone:NO];
    }
}

代码在没有 ARC 的情况下(以及适当的版本)编译时可以工作,但是当它转换为 ARC 时,它会在完成 main 方法后立即收到 EXC_BAD_ACCESS 异常。

我猜这与 ARC 提前释放任何对象有关,也许是 Posts 对象。但我不知道如何将它们保留更长时间。

此外,[[Post alloc] initWithNewManagedObjectContext]; 创建或重用现有上下文以从 CoreData 访问对象。

有什么提示吗?

【问题讨论】:

  • 使用NSZombiesEnabled 运行仪器。这对解决这类问题有很大帮助。
  • 什么是目标?你对它有强烈的引用吗?如果您没有强引用,它将在performSelectorOnMainThread: 可以运行之前立即被解除分配...这意味着您将向解除分配的对象发送消息。
  • post 也将被释放,除非您在其他地方引用它。

标签: ios objective-c core-data exc-bad-access nsoperation


【解决方案1】:

其实是朋友帮我找到问题的。 感谢每一条评论。

问题在于NSManagedObjectContext,它正在被后台线程访问。

解决方案是为后台线程创建一个新上下文,使用的技巧是将上下文存储在 threadDictionary 上,以便其他后台线程在需要时访问。

所以现在,[[Post alloc] initWithNewManagedObjectContext]; 创建了一个单独的上下文:

NSManagedObjectContext *managedObjectContext = nil;
NSThread *thread = [NSThread currentThread];
managedObjectContext = [[thread threadDictionary] valueForKey:@"managedObjectContext"];

if (!managedObjectContext) {
    GTCoreData *gtcd = [[GTCoreData alloc] init];
    NSPersistentStoreCoordinator *coordinator = [gtcd persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator:coordinator];
        [[thread threadDictionary] setValue:managedObjectContext forKey:@"managedObjectContext"];
    }
}

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:managedObjectContext];
Post *post = [[Post alloc] initWithEntity:entity insertIntoManagedObjectContext:managedObjectContext];
return post;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2012-12-06
    • 1970-01-01
    • 2021-12-11
    • 2015-04-18
    相关资源
    最近更新 更多