Swift:在后台同步CoreData对象

时间:2017-10-17 12:42:47

标签: ios swift core-data concurrency

我需要在后台将CoreData对象上传到API服务器。为此,我创建了一个新的私有上下文作为主要上下文的子项,并对其进行perform()。我使用此上下文从对象获取JSON数据,并在上载后将一些数据写入对象。

似乎一切正常,但我有些疑惑。

下面是一个显示案例的简单示例。上下文在第二个函数中是否有一些强引用?我应该在某个地方对我的新语境进行一些强有力的参考吗?

// ViewController.swift
func uploadObject(_ currentObject: MyManagedObject) {
    // we are in the main thread, go to another thread
    let objectId = currentObject.objectID
    let context = getNewPrivateContext()    // child context of the main context
    context.perform {
        if let object = context.object(with: objectId) as? MyManagedObject {
            SyncManager.shared.uploadObject(_ object: object, completion: {
                // ... update UI
            })
        }
    }
}

// SyncManager.swift
func uploadObject(_ object: MyManagedObject, completion: ()->()) {
    // does the context has some strong reference here?
    guard let context = object.managedObjectContext { completion(); return }

    let params = getJson(with: object)
    // ... prepare url, headers
    Alamofire.request(url, method: .put, parameters: params, encoding: JSONEncoding.default, headers: headers)
        .responseJSON( completionHandler: { (response) in
            // ... parse the response
            context.perform {
                // ... write some data to the Core Data and save the context
                completion()
            }
        })
}

修改

另外一个lldb问题支持我的怀疑:

(lldb) po context
error: <EXPR>:3:1: error: use of unresolved identifier 'context'
context
^~~~~~~

1 个答案:

答案 0 :(得分:0)

它是一个强大的参考,但它是不安全的,这意味着如果从它的上下文中删除接收器(对象),它将返回nil。

就我而言,我会使用if let声明而不是警卫:

func uploadObject(_ object: MyManagedObject, completion: ()->()) {
    // does the context has some strong reference here?
    if let context = object.managedObjectContext {

        let params = getJson(with: object)
        // ... prepare url, headers
        Alamofire.request(url, method: .put, parameters: params, encoding: JSONEncoding.default, headers: headers)
    .responseJSON( completionHandler: { (response) in
            // ... parse the response
            context.perform {
                // ... write some data to the Core Data and save the context
                completion()
            }
        })
    } else {
        completion()
    }
}