Swift:在后台同步核心数据对象
Posted
技术标签:
【中文标题】Swift:在后台同步核心数据对象【英文标题】:Swift: synchronise CoreData object in background 【发布时间】:2017-10-17 12:42:47 【问题描述】:我需要在后台将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
^~~~~~~
【问题讨论】:
我觉得一切都很好 请注意context.object(with: objectId)
将为您生成一个新对象。你可能想要existingObject(with:)
【参考方案1】:
这是一个强引用,但它是不安全的,这意味着如果接收者(对象)从其上下文中删除,它将返回 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()
【讨论】:
将guard
更改为if let
没有意义。这只是增加了不必要的代码嵌套。
很抱歉 :),那是我看到的唯一问题...您正在保存 privateMOC,这会将其更改推送到其父 MOC...我不是这个意思更好,只有两种不同的方式来处理选项。只有在设置context
时才会运行代码块的两种方式
其实你的context
可能会随着范围的变化而被释放。设置断点,然后运行po context.userInfo
或po context.persistentStoreCoordinator
。我通常在我的协调器类中保存两个 MOC 对象,一个是主对象,一个是私有对象,用于在后台解析数据/写入数据。我说这是一个强引用,因为查看 Apple 对象引用中的属性将其简单地列为 var
,只要文档正确,它就会变得强大。
谢谢。现在我知道managedObjectContext
是强大但不安全的属性。我认为这是弱属性。 ) 请看我对帖子的编辑。由于某种原因,我不能po context
。以上是关于Swift:在后台同步核心数据对象的主要内容,如果未能解决你的问题,请参考以下文章