Core Data MagicalRecord:获取请求并保存在多线程中。锁定获取的对象?
Posted
技术标签:
【中文标题】Core Data MagicalRecord:获取请求并保存在多线程中。锁定获取的对象?【英文标题】:Core Data MagicalRecord: fetch request and save in multithreading. Lock fetched objects? 【发布时间】: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)
];
【问题讨论】:
【参考方案1】:对于第一个问题,不要选择任何一个选项。相反,请使用NSFetchedResultsController
。
对于第二个问题,您的第一个选项是正确的选项。您应该打开一个上下文并执行所有更改并让 Magical Record 处理保存所有更改。
如果您选择第二个选项,您仍然会执行相同数量的操作,但您会打开许多上下文。
第一个选项:
saveWithBlock: // Called once
enumerateObjectsWithOptions: // Called once
第二个选项
saveWithBlock: // Called many times (once for each object)
enumerateObjectsWithOptions: // Called once
【讨论】:
以上是关于Core Data MagicalRecord:获取请求并保存在多线程中。锁定获取的对象?的主要内容,如果未能解决你的问题,请参考以下文章
Plain Core Data vs Core Data + Magical Record
导入与 Core Data 和 Magical Record 的关系
如何在 Core Data 和 Magical Record 中存储一系列电子邮件
尝试将服务器内容同步到 Core Data 时出现问题 - Magical Record 插入过程非常慢