我正在从json中的网站加载信息到本地Core Data。我创建了两个NSManagedObject的子类:
@objc(Category)
class Category: NSManagedObject {
@NSManaged var id: NSNumber
@NSManaged var name: String
}
@objc(Event)
class Event: NSManagedObject {
@NSManaged var category: String
@NSManaged var date: String
@NSManaged var event: String
@NSManaged var location: String
@NSManaged var time: String
}
以下是我在后台加载信息的代码:
func loadAllData(){
println("loading all data")
progressCounter = 0
let source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
dispatch_source_set_event_handler(source) {
[unowned self] in
self.progressCounter += dispatch_source_get_data(source)
self.progressView.setProgress(Float(self.progressCounter) / Float(self.maxValue), animated: true)
}
dispatch_resume(source)
let params = ServerConstants.infoParam + "=true"
// creating request, set its method to POST and append params to request
var request = NSMutableURLRequest(URL: NSURL(string: ServerConstants.getInfoURL)!)
request.HTTPMethod = "POST"
request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
//request.setValue("Basic \(base64LoginString!)", forHTTPHeaderField: "Authorization")
//start loading data in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if error == nil {
let json = JSON(data: data)
//println(json)
self.maxValue = Float(json["categories"].count + json["events"].count)
println("maxself. - \(self.maxValue)")
var array = json["categories"]
var maxIndex = array.count
var error: NSError?
for var i: Int = 0; i < maxIndex; i++ {
if let moc = self.context {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("Category", inManagedObjectContext: self.context!) as! Category
newItem.id = array[i]["id"].string!.toInt()!
newItem.name = array[i]["name"].string!
dispatch_source_merge_data(source, 1);
moc.save(&error)
}
}
array = json["events"]
maxIndex = array.count
for var i: Int = 0; i < maxIndex; i++ {
if let moc = self.context {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("Event", inManagedObjectContext: moc) as! Event
newItem.category = array[i]["category"].string!
newItem.event = array[i]["event"].string!
newItem.location = array[i]["location"].string!
newItem.date = array[i]["date"].string!
newItem.time = array[i]["time"].string!
dispatch_source_merge_data(source, 1);
moc.save(&error)
}
}
println("done")
dispatch_async(dispatch_get_main_queue()){
self.showScreenElements()
}
}
}
task.resume()
}
}
我的服务器数据库大约有3600行,下载过程需要大约30-40秒才能加载。
有没有更好的方法来更快地获取服务器的json?
当我试图在200次迭代时只保存一次时,它会抛出一个错误
EXC_BAD_ACCESS
for var i: Int = 0; i < maxIndex; i++ {
if let moc = self.context {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("Event", inManagedObjectContext: moc) as! Event
newItem.category = array[i]["category"].string!
...
dispatch_source_merge_data(source, 1);
if i % 200 == 0 {
moc.save(&error)
}
}
}
self.context!.save(&error)
println("done")
我会尝试使用performBlock并告诉你我的结果。
答案 0 :(得分:0)
你经常保存。尝试分批保存,比如500次左右插入后。
此外,尝试切换此操作的上下文的撤消管理器。假设您有一个可以丢弃的子环境:
context.undoManager = nil
此外,您的GCD代码非常复杂。您是否查看了performBlock
的{{1}}和performBlockAndWait
API?