【发布时间】:2019-09-27 13:42:26
【问题描述】:
如标题所述,我在后台线程保存对象后,其属性在主线程上为空,例如字符串为"",数字为0等。
这里有一些代码!
用户类别:
@objc(User)
class User: NSManagedObject {
@NSManaged var id: Int32
@NSManaged var email: String
}
进行实际保存的用户存储库:
func saveUser(fromJSON json: Any, onSuccess: ((User) -> Void)?, onFailure: ((Error) -> Void)?) {
dataManager.persistentContainer.performBackgroundTask { context in
context.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
let user = self.userFactory.user(fromJSON: json, inContext: context)
// print(user.id) and print(user.email) output correct data
do {
try context.save()
DispatchQueue.main.async {
// print(user.id) and print(user.email) show 0 and ""
onSuccess?(user)
}
} catch let error {
DispatchQueue.main.async {
onFailure?(error)
}
}
}
}
dataManager 的配置如下:
class CoreDataManager {
private let modelName: String
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: modelName)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
})
return container
}()
init(modelName: String) {
self.modelName = modelName
}
}
我猜userFactory 不是那么重要,但为了完整起见:
class UserFactory {
func user(fromJSON json: Any, inContext context: NSManagedObjectContext) -> User {
guard
let jsonDictionary = json as? [String: Any?],
let userDictionary = jsonDictionary["user"] as? [String: Any?],
let id = userDictionary["id"] as? Int32,
let email = userDictionary["email"] as? String
else {
fatalError("Could not parse User object.")
}
let user = User(context: context)
user.id = id
user.email = email
return user
}
}
请参阅上面 sn-ps 中有关打印语句的 cmets,这些语句指出了用户属性正常的位置以及它们显示 0 和 "" 的位置。
我知道我无法在线程之间传递 NSManagedObjects,但即使我尝试使用 DispatchQueue.main.async 块中的 objectID (NSManagedObjectID) 获取用户对象,用户属性仍然是空的。
我想我做错了什么,但不能指手画脚。任何建议将不胜感激。
提前非常感谢!
【问题讨论】:
-
当你说
user.id = id和user.email = email时,你确定这些不是nil吗? -
是的,我有 - 在上面的守卫声明中,在工厂里。
-
哦,是的,我明白了,愚蠢的我,对不起。 - 顺便说一句,我真的很喜欢格式化
guard列表的方式。我将在我自己的代码中采用它! -
谢谢你,很高兴你喜欢它!是的,我认为当有超过 1 个语句时它很容易阅读。