我正在将 json 格式的信息从站点加载到本地核心数据。我创建了 NSManagedObject 的 2 个子类:
@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并告诉你我的结果。
最佳答案
您存钱太频繁了。尝试批量保存,例如插入 500 次左右后。
此外,尝试切换此操作的上下文的撤消管理器。假设您有一个可以丢弃的子上下文:
context.undoManager = nil
此外,您的 GCD 代码非常复杂。您查看过 NSManagedObjectContext
的 performBlock
和 performBlockAndWait
API 吗?
关于ios - 从服务器数据库加载信息的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31619850/