我需要从csv加载大量数据 为了避免UI冻结,我必须在不同的线程上执行此操作。
@objc(Person)
class Person: NSManagedObject {
@NSManaged var name: String?
}
func createDummies(completion : (success : Bool, result: [Person]?, error : NSError?) -> Void) {
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, { () -> Void in
var res: [Person] = []
for var i = 0; i < 10; ++i {
let p = Person.MR_CreateEntity
res.append(p)
}
completion(success: true, result: p, error: nil)
})
}
func loadDummies() {
createDummies({ (success, result, error) -> Void in
MagicalRecord.saveWithBlock { (m: NSManagedObjectContext!) -> Void in
let persons = Person.MR_findAll() as? [Person]
println("block \(persons)")
}
let persons = Person.MR_findAll() as? [Person]
println("out block \(persons)")
}
}
此代码产生一个奇怪的输出:
block Optional([])
out block Optional([ <Person: 0x7fd0224129e0> (entity: Person;] ..... etc)
因此,如果在此之后我在另一个视图控制器中调用Person.MR_FindAll,则结果为空数组。
有什么想法吗?我认为问题是在不同的线程中创建和保存实体:如果是这种情况,我该如何解决这个问题呢?
答案 0 :(得分:1)
核心数据对象不是线程安全的!并且您不应该对核心数据的主要上下文进行大量更新/保存,它会冻结您的UI。如果您使用NSFetchResultController委托的子父上下文方法,那么如果您的背景上下文是UI上下文的子项,则UI上的数据将自动更新。 UI上下文应为NSMainQueueConcurrencyType
类型,子(背景)上下文应为NSPrivateQueueConcurrencyType
类型。NSManagedObjectContext
具有performBlockAndWait
和performBlock
方法应该执行获取和更新。