CoreData应用程序在执行获取请求pthread_mutex_lock时冻结

时间:2012-07-24 12:17:34

标签: iphone ios multithreading ios5 core-data

我正在使用Core Data管理我的应用程序的数据库。

我不能在这里发布代码,因为它太冗长了。但我想我可以用一小段代码解释我的问题以及一些快照。

+(NSArray *)checkusernameandpassword:(NSString *)entityname  username:(NSString *)username   password:(NSString *)password 
{
    managedobjectcontext=[Singleton sharedmysingleton].managedobjectcontext;
    NSEntityDescription *entity=[NSEntityDescription entityForName:entityname inManagedObjectContext:managedobjectcontext];

    NSFetchRequest *request=[[NSFetchRequest alloc] init];
    [request setEntity:entity];

    NSPredicate *predicates=[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"userName==\"%@\" AND password==\"%@\"",username,password]];
    [request setPredicate:predicates];  
    //On Below line, My app frezes and goes into deadlock, this happens randomly while performing
    //some data request using Core data
    NSArray *arrayofrecord=[managedobjectcontext executeFetchRequest:request error:nil];    

    return arrayofrecord;
}

我正在尝试附加一些电话的屏幕截图(我在暂停应用时会看到这些) 上图中提到了图像中带有复选标记的方法 The method with a checkmark in the image,at which deadlock occur is mentioned above

3 个答案:

答案 0 :(得分:3)

你必须锁定线程。当多个线程访问同一段代码时,会出现此问题。但最终还是要陷入僵局。

static NSString *fetchRequest = @"fetchRequest";
    NSArray *results;
    @synchronized (fetchRequest){
        managedobjectcontext=[Singleton sharedmysingleton].managedobjectcontext;
        NSEntityDescription *entity=[NSEntityDescription entityForName:entityname inManagedObjectContext:managedobjectcontext];

        NSFetchRequest *request=[[NSFetchRequest alloc] init];
       [request setEntity:entity];

       NSPredicate *predicates=[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"userName==\"%@\" AND password==\"%@\"",username,password]];
       [request setPredicate:predicates];  
       //On Below line, My app frezes and goes into deadlock, this happens randomly while performing
       //some data request using Core data
       results = [managedobjectcontext executeFetchRequest:request error:nil];    
}
return results;

答案 1 :(得分:0)

据我所知,你可以在转储中理解CoreData Context,而不是MainThread。

请记住,CoreData Context不是线程安全的,并且您有责任正确使用它。

Apple documentation about CoreData and Thread非常详尽。

上面提出的解决方案根本不安全:如果您在并发环境中编程,则synchronized语句是无用的(即,您有多个线程,我们假设它们可以同时访问相同的MOC)。

您可以尝试在线程生命周期中“限制”您的上下文。例如:

dispatch_async(dispatch_get_global_queue(0, 0), ^(){
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;

//Make the fetch and export results to main thread
...
}); 

答案 2 :(得分:-1)

在多线程环境中使用Core Data时,您可以尝试[private performBlock:^{}];

有关详细信息,请查看此文档https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html#//apple_ref/doc/uid/TP40001075-CH24-SW1