【问题标题】:Core Data MagicalRecord: fetch request and save in multithreading. Lock fetched objects?Core Data MagicalRecord:获取请求并保存在多线程中。锁定获取的对象?
【发布时间】:2014-11-03 12:43:44
【问题描述】:

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

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

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

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

在 fetchRequest 期间如何锁定 Company 对象?

代码示例:

先打电话:

+ (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)

    }
];

【问题讨论】:

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


    【解决方案1】:

    对于第一个问题,不要选择任何一个选项。相反,请使用NSFetchedResultsController

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

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

    第一个选项:

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

    第二个选项

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多