核心数据MagicalRecord:获取请求并保存在多线程中。锁定取物?

时间:2014-11-03 12:43:45

标签: objective-c multithreading macos core-data magicalrecord

我正在使用MagicalRecord。保存一些ManagedObject(例如“公司”)后,我立即发送通知重新加载公司的TableView并创建其他对象(例如“People”)。

每个方法“addPeople”执行[Company findAllWithPredicate:...@"(lastUpdateDate == nil)"]并生成arrayOfCompany

然后我用arrayOfCompany迭代enumerateObjectsWithOptions:NSEnumerateConcurrent。 每次迭代都会很长时间。

在下一次拦截通知期间结果并调用“addPerson”会返回公司的相同对象。在每个创建的线程中,我都使用相同的对象。

fetchRequest期间锁定公司对象的方式

代码示例:

先致电:

+ (void)addCompany
{
    ...
    [arrayOfCompanies enumerateObjectsWithOptions:NSEnumerateConcurrent
                                      usingBlock:^(Company *obj, NSUInteger idx, BOOL *stop)
    {
        [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
            Company *company = [Company createEntityInContext:localContext];
            ....
        }
        completion:^(BOOL contextDidSave, NSError *error){
            if (contextDidSave)
            {
                [[NSNotificationCenter defaultCenter] postNotificationName:@"newCompanyJustAdded" 
                                                                    object:nil];
            }
        }];
    }];
}

通知捕获:

+ (void)newCompanyJustAdded:(NSNotification *)notification
{
    [Person addPersons];
}

+ (void)addPersons
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        predicate = @"(lastUpdateDate == nil)";
        NSArray *companysInCoreData = [Company findAllWithPredicate:predicate];

        [companysInCoreData enumerateObjectsWithOptions:NSEnumerateConcurrent
                                             usingBlock:^(id obj, NSUInteger idx, BOOL *stop)
        {
            NSManagedObjectContext *local_context = [NSManagedObjectContext contextForCurrentThread];
            Company *local_company_obj = [obj inContext:local_context];
            ...
            local_company_obj.lastUpdateDate = [NSDate date];
            [local_context saveToPersistentStoreAndWait];
            ...
            ...
            [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
            {
                Person *person = [Person createEntity];
                person.name = ...
                ...
            });
        }];
    });
}

我的第二个问题:

什么是对的:

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
{
    [someArray enumerateObjectsWithOptions:usingBlock
    {

    }
}];

[someArray enumerateObjectsWithOptions:usingBlock
{
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)

    }
];

1 个答案:

答案 0 :(得分:0)

对于第一个问题,请勿执行其中任何一个选项。相反,请使用NSFetchedResultsController

对于第二个问题,您的第一个选项是正确的选项。您应该打开一个上下文并执行所有更改,并让Magical Record处理保存所有更改。

如果你使用第二个选项,你仍然会执行相同数量的操作,但是你会打开许多​​上下文。

第一个选项:

saveWithBlock: // Called once
enumerateObjectsWithOptions: // Called once

第二个选项

saveWithBlock: // Called many times (once for each object)
enumerateObjectsWithOptions: // Called once