核心数据:在NSUrlRequest中更新的正确方法

时间:2016-10-27 13:08:24

标签: ios swift xcode core-data

我有一个NSUrlRequest,我在其中调用方法User.updateMyObject(id: NSNumber, name: String)。对象User具有静态属性:

static let appDelegate = UIApplication.shared.delegate as! AppDelegate
static let MOC = appDelegate.managedObjectContext

有几种更新/创建/删除对象的方法。

现在,我已经读过你不应该在不同的线程上使用MOC。据我所知,NSUrlRequest以异步方式运行。那我怎么去打电话MyObject.updateMyObject(id: NSNumber, name: String)

我有时会收到错误:

CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'

我的请求如下:

let session = URLSession.shared
    // The singleton shared session is for basic requests.
    // Data tasks send and receive data using NSData objects.
    // Data tasks are intended for short, often interactive requests to a server.
    let task = session.dataTask(with: request) {
        (data: Data?, response: URLResponse?, error: Error?) in

    //JSon parsing
    MyObject.updateMyObject(id: NSNumber, name: String)
} 
task.resume()

MyObject.updateMyObject(id: NSNumber, name: String)看起来像这样:

static func updateMyObject(id: NSNumber, name: String) {
    let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "MyObject")
    let resultPredicate = NSPredicate(format: "id = \(id)")
    request.predicate = resultPredicate

    do {
        let result = try User.MOC.fetch(request).first as! MyObject

        result.name = name

        User.appDelegate.saveContext()
    }
    catch {
        print("User.updateMyObject: error.")
    }
}

1 个答案:

答案 0 :(得分:1)

这就是perform上存在performAndWaitNSManagedObjectContext方法的原因 - 这样您就可以安全地在不同的线程上使用上下文。你应该在这里使用其中一个。

通常,每当您触摸与Core Data相关的任何内容时,您需要将该代码包装在对这两种方法之一的调用中。这些方法以闭包为参数;将您的Core Data代码放入该闭包中。此规则的唯一例外是,如果您使用mainQueueConcurrencyType ,则表示您的代码正在主队列上运行。