如何在线程中使用ManagedObjectContext [英] How to use ManagedObjectContext with threads

查看:98
本文介绍了如何在线程中使用ManagedObjectContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个非常简单的应用程序,但是我不熟悉Objective-C(来自Java),整个内存管理和"EXC_BAD_ACCESS"错误都让我伤心.

This is probably a very straight forward application, but I am new to Objective-C (coming from Java) and the whole memory management and "EXC_BAD_ACCESS" errors are breaking my heart.

我有一个带有Core Data的普通NavigationController iPhone应用程序.在AppDelegate中,将创建NSManagedObjectContext并将其传递给RootViewController.在视图中,可以直接从主线程查找事物以填充表,这似乎很好.

I have a normal NavigationController iPhone App, with Core Data. in the AppDelegate the NSManagedObjectContext is created and passed to the RootViewController. A view things are looked up directly from the main thread to populate the table, and that seems to work fine.

该应用程序类似于RSS类型的阅读器,因此,一旦该应用程序启动,我就会触发一个线程来获取新数据并更新视图:

The App is somekind of RSS-type reader, so as soon as the App starts I fire a thread to fetch new data and update the view:

-(void)updateData:(id)sender {
 UIActivityIndicatorView *activityIndicator =
    [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
 [activityIndicator startAnimating];
 UIBarButtonItem *activityItem =
    [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
 [activityIndicator release];
 self.navigationItem.leftBarButtonItem = activityItem;
 [activityItem release];

 // Start thread to update the data
 [NSThread detachNewThreadSelector:@selector(doUpdateData) toTarget:self withObject:nil];
}

-(void)doUpdateData{
 NSLog(@"Update data Thread (in 5 sec.)");
 [NSThread sleepForTimeInterval:5];

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

 DataManager *data = [[DataManager alloc] initWithContext:managedObjectContext];
 [data updateData];
 [data release];
 data=nil;

 [self performSelectorOnMainThread:@selector(finishUpdateData) withObject:nil waitUntilDone:NO]; 
 [pool release];
}

-(void)finishUpdateData{
 self.navigationItem.leftBarButtonItem = updateBttn;
 DataManager *data = [[DataManager alloc] initWithContext:managedObjectContext];
 objects = [data getArticles];
 [data release];
 data=nil;
 NSLog(@"Amount of records after update: %d", [objects count]);
 [self.tableView reloadData]; 
}

问题是这不起作用.在DataManager中,需要检索第一个设置,并且在创建NSEntityDescription后,我立即获得"EXC_BAD_ACCESS":

The problem is that this doesn't work. In the DataManager, first settings need to be retrieved, and as soon as the NSEntityDescription is created I get the "EXC_BAD_ACCESS":

- (NSFetchedResultsController *)fetchedResultsController {
    // Set up the fetched results controller if needed.
    if (fetchedResultsController == nil) {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Setting" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"key" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

        [fetchRequest setSortDescriptors:sortDescriptors];
  [fetchRequest setFetchLimit:1]; 
        .
        NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];

        aFetchedResultsController.delegate = self;
        self.fetchedResultsController = aFetchedResultsController;

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];
    }

 return fetchedResultsController;
} 

由于运行在不同的线程和内存池中,导致我猜到ManagedObjectContext的指针是错误的.那么,如果出现问题,那么如何创建这样的应用程序),如何获得对他所使用的原始ManagedObjectContext格式的引用?

I guess the pointer to the ManagedObjectContext is wrong, as a result from running in a different thread and memory-pool. So how do you create such an application if that is the issue), how do I get a reference to the original ManagedObjectContext format he thread?

我也尝试使用

iDomsAppDelegate *appDelegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
DataManager *data = [[DataManager alloc] initWithContext:appDelegate.managedObjectContext];

在doUpdateData中(如其他帖子所暗示的),但给出的结果相同

in doUpdateData (as hinted by other posts), but that gives the same result

推荐答案

受管对象上下文不是线程安全的. Apple指南表示您必须每个线程有一个单独的NSManagedObjectContext实例.

Managed Object Contexts are not thread safe. Apple's guidelines indicate that you must have a separate instance of NSManagedObjectContext per thread.

这篇关于如何在线程中使用ManagedObjectContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆