2013-02-25 100 views
0

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

所以,我有我的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收到的EXC_BAD_ACCESS在完成主要方法后异常。

我想这是与ARC发布任何对象之前它应该,也许是帖子对象有关的东西。但我不知道如何长时间保留它们。

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

任何提示?

+1

运行文书'NSZombiesEnabled'。这对这类问题有很大的帮助。 – borrrden 2013-02-26 01:13:42

+0

什么是目标?你是否保持强烈的参考?如果你没有强引用,它会立即释放,在'performSelectorOnMainThread:'可以运行之前......这意味着你将发送一个消息给一个释放对象。 – nielsbot 2013-02-26 02:24:46

+0

'post'也将被释放,除非你在其他地方有一个引用。 – nielsbot 2013-02-26 02:25:38

回答

0

其实,一位朋友帮我找到了问题。 感谢每一条评论。

问题出在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;