我工作的現有項目,使用CoreData,即:CoreData阻塞UI
把從不同CoreData實體類型很多很多的項目,從網絡服務接收它們之後,卻塊多秒UI線程,即使我在另一個線程中使用它。
請幫助我,有沒有什麼辦法可以防止CoreData以最小的變化阻止UI,因爲項目幾乎完成了?
我是CoreData
的新手,不幸的是我沒有足夠的時間研究文檔或重新編寫源代碼。
我DataController類:
class DataController {
var managedObjectContext: NSManagedObjectContext
let modelName = "something"
init(closure:()->()) {
guard let modelURL = NSBundle.mainBundle().URLForResource(modelName, withExtension: "momd"),
let managedObjectModel = NSManagedObjectModel.init(contentsOfURL: modelURL)
else {
fatalError("DataController - COULD NOT INIT MANAGED OBJECT MODEL")
}
let coordinator = NSPersistentStoreCoordinator.init(managedObjectModel: managedObjectModel)
managedObjectContext = {
let parentContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
parentContext.persistentStoreCoordinator = coordinator
let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.parentContext = parentContext
return managedObjectContext
}()
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
let options = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true,
NSSQLitePragmasOption: ["journal_mode": "DELETE"]
]
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last
let storeURL = NSURL.init(string: "something", relativeToURL: documentsURL)
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: options)
dispatch_async(dispatch_get_main_queue()) {
closure()
}
}
catch let error as NSError {
fatalError("DataController - COULD NOT INIT SQLITE STORE: \(error.localizedDescription)")
}
}
}
func save(moc: NSManagedObjectContext? = nil) {
var managedObjectContext = moc
if moc == nil {
managedObjectContext = self.managedObjectContext
}
managedObjectContext!.performBlockAndWait {
if managedObjectContext!.hasChanges {
do {
try managedObjectContext!.save()
} catch {
print("ERROR saving context \(managedObjectContext!.description) - \(error)")
}
}
if let parentContext = managedObjectContext!.parentContext {
self.save(parentContext)
}
}
}
}
我的班是一樣的東西:
class MOCity: NSManagedObject {
@NSManaged var id: NSNumber?
@NSManaged var name: String?
// Insert code here to add functionality to your managed object subclass
class func save(id: NSNumber, json: JSON, managedObjectContext: NSManagedObjectContext) {
guard let newObject = MOCity.getById(id, create: true, managedObjectContext: managedObjectContext) else {
fatalError("City - NO OBJECT")
}
newObject.id <-- json["Id"]
newObject.name <-- json["Name"]
}
internal class func getById(id: NSNumber, create: Bool = false, managedObjectContext: NSManagedObjectContext) -> MOCity? {
let fetchRequest = NSFetchRequest(entityName: "City")
fetchRequest.predicate = NSPredicate(format: "id = \(id)")
do {
guard let fetchResults = try managedObjectContext.executeFetchRequest(fetchRequest) as? [MOCity] else {
fatalError("city - NO FETCH RESULTS")
}
if fetchResults.count > 0 {
return fetchResults.last
}
else if fetchResults.count == 0 {
if create {
guard let object = NSEntityDescription.insertNewObjectForEntityForName("City", inManagedObjectContext: managedObjectContext) as? MOCity else {
fatalError("getCity - COULD NOT CREATE OBJECT")
}
return object
} else {
return nil
}
}
}
catch let error as NSError {
...
}
return nil
}
}
我的Web服務類:
Alamofire.request(.POST, url,parameters:data).validate().responseJSON(completionHandler: {response in
switch response.result {
case .Success:
if let jsonData = response.result.value {
if let array = jsonData as? NSArray {
for arrayItem in array {
MOCity.save(arrayItem["Id"] as! NSNumber, json: JSON(arrayItem as! NSDictionary)!, managedObjectContext: self.dataController.managedObjectContext)
}
self.dataController.save()
}
}
break
case .Failure(let error):
...
}
})
我試過使用它,但是它在覈心數據操作中造成了崩潰。任何解決方案或示例代碼請? –
嗯,我會調查你的代碼更多。 –
謝謝,我會等你的幫助。 :) –