0

我试图了解如何在核心数据中运行同时搜索。

这是我的示例,但它不起作用,因为其中一个 GCD 似乎永远不会激活如果我将 custon MOC 留在那里,我会收到错误“无法找到实体 'Recipe' 的模型”

-(void)performSearch:(NSString*)name{

    //TODO: Is there a better way

    //In case the previous search hasn't finished
    if (globaDispatchRequestInprogress) {
        //Send on GCD
        dispatch_queue_t searchQueque = dispatch_queue_create("search queque 2", NULL);
        dispatch_async(searchQueque, ^{
            NSLog(@"\n\nDispatch 2 In Progress*******\n\n");


            //Init local variables
            NSFetchRequest *fetchRequest =[[NSFetchRequest alloc]init];
            NSError *error;


             //Create own MOC for multiThread
             NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc]init];

             [tempContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];


            NSPredicate *recipeName = [NSPredicate predicateWithFormat:@"ANY recipe.name ==[c] %@",name];

            //Set predicate to fetch request
            [fetchRequest setPredicate:recipeName];

            //Set query. We are searching recipes
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:tempContext];
            //sets up fetch request details
            [fetchRequest setEntity:entity];

            //Attempt to speed up program
            [fetchRequest setReturnsObjectsAsFaults:NO];


            //Perform fetch assign to return array
            NSArray*records = [tempContext executeFetchRequest:fetchRequest error:&error];

            //Add to temporary results
            //TODO: Add to NSDictionary
            [self addResultsToTemporaryResults:records];

            NSLog(@"Total results = %i",[_temporaryResultsArray count]);

            NSLog(@"\n\nDispatch 2 END**************\n\n");

        });

    }
    //Send on GCD
    dispatch_queue_t searchQueque = dispatch_queue_create("search queque", NULL);
    dispatch_async(searchQueque, ^{
        NSLog(@"\n\nDispatch In Progress*******\n\n");

        //Set flag
        globaDispatchRequestInprogress=YES;

        //Init local variables
        NSFetchRequest *fetchRequest =[[NSFetchRequest alloc]init];
        NSError *error;


         //Create own MOC for multiThread
         NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc]init];

         [tempContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];

        NSPredicate *recipeName = [NSPredicate predicateWithFormat:@"ANY recipe.name ==[c] %@",name];

        //Set predicate to fetch request
        [fetchRequest setPredicate:recipeName];

        //Set query. We are searching recipes
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:tempContext];
        //sets up fetch request details
        [fetchRequest setEntity:entity];

        //Attempt to speed up program
        [fetchRequest setReturnsObjectsAsFaults:NO];

        //Perform fetch assign to return array
        NSArray*records = [tempContext executeFetchRequest:fetchRequest error:&error];

        //Add to temporary results
        //TODO: Add to NSDictionary
        [self addResultsToTemporaryResults:records];

        NSLog(@"Total results = %i",[_temporaryResultsArray count]);
        globaDispatchRequestInprogress=NO;

        NSLog(@"\n\nDispatch END**************\n\n");

    });

}
4

1 回答 1

2

我看到了几件让我怀疑的事情,但没有明显的确凿证据。

如果您看到“无法找到模型”,则表明您的持久存储协调器没有按照您认为的方式进行配置。NSLog self.persistentStoreCoordinator.managedObjectModel 和 self.persistentStoreCoordinator.managedObjectModel.entitiesByName 会很有趣。

Core Data 的首选 GCD 方法是使用 performBlock: 或 performBlockAndWait:,为托管对象上下文提供适当的并发类型。请参阅http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/index.html

您在 addResultsToTemporaryResults: 调用中保留了 fetch 的结果。我们看不到它的来源,但它是线程安全的吗?您找到的那些记录在您获取它们的 tempContext 之外不存在,并且只能从找到它们的线程中访问。您可能希望在那里使用 NSManagedObjectIDs(也许您已经在使用)。

您对 dispatch_queue_create() 的第二次调用将始终被执行。你的意思是做一个if-else而不是一个简单的if吗?

When you do -executeFetchRequest:error:, check the result. If it's a nil result, take a look at the NSError you passed in.

于 2013-03-21T21:33:39.080 回答