Swift 2 在 appDelegate 中迁移 saveContext()
Swift 2 migration saveContext() in appDelegate
我刚刚下载了新的 Xcode 7.0 beta 并从 Swift 1.2 迁移到 Swift 2。迁移显然没有改变整个代码,实际上是方法 saveContext() 一直很好,直到为该行抛出 2 个错误:
if moc.hasChanges && !moc.save() {
Binary operator '&&' cannot be applied to two Bool operands
和
Call can throw, but it is not marked with 'try' and the error is not handled
该方法如下所示:
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save() {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
关于如何让它工作有什么想法吗?
您提供的两个错误中的第一个具有误导性,但第二个是正确的。问题出在 !moc.save()
中,从 Swift 2 开始,不再是 returns Bool,而是注释为 throws
。这意味着您必须 try
此方法和 catch
它可能发出的任何异常,而不仅仅是检查其 return 值是真还是假。
为了反映这一点,在 Xcode 7 中使用 Core Data 创建的新项目将生成以下样板代码,可以替换您正在使用的代码。
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
0x7fffffff 的回答是正确的,但要改进 Apple 的样板代码,您可以使用 catch let error as NSError
在 catch 块中捕获特定错误,如下所示:
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch let error as NSError {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
最好的做法是使用 var error
如果您只是这样使用它,它仍然可用:
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
同理,如果你确定managedObjectContext.save()
不会throw
和exception
,代码精简为:
func saveContext () {
if managedObjectContext.hasChanges {
try! managedObjectContext.save()
}
}
并推断为什么 managedObjectContext
在 Swift 2 代码中不是可选的,这是因为 NSManagedObject(concurrencyType:)
是一个不会失败的初始化程序。在 Xcode 6 中,如果 NSPersistentStoreCoordinator
为 nil,则样板代码返回一个可选上下文,但您可以通过检查轻松处理此问题。
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
moc.persistentStoreCoordinator = coordinator
return moc
}()
我刚刚下载了新的 Xcode 7.0 beta 并从 Swift 1.2 迁移到 Swift 2。迁移显然没有改变整个代码,实际上是方法 saveContext() 一直很好,直到为该行抛出 2 个错误:
if moc.hasChanges && !moc.save() {
Binary operator '&&' cannot be applied to two Bool operands
和
Call can throw, but it is not marked with 'try' and the error is not handled
该方法如下所示:
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save() {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
关于如何让它工作有什么想法吗?
您提供的两个错误中的第一个具有误导性,但第二个是正确的。问题出在 !moc.save()
中,从 Swift 2 开始,不再是 returns Bool,而是注释为 throws
。这意味着您必须 try
此方法和 catch
它可能发出的任何异常,而不仅仅是检查其 return 值是真还是假。
为了反映这一点,在 Xcode 7 中使用 Core Data 创建的新项目将生成以下样板代码,可以替换您正在使用的代码。
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
0x7fffffff 的回答是正确的,但要改进 Apple 的样板代码,您可以使用 catch let error as NSError
在 catch 块中捕获特定错误,如下所示:
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch let error as NSError {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
最好的做法是使用 var error
如果您只是这样使用它,它仍然可用:
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
NSLog("Unresolved error \(error), \(error.userInfo)")
// Handle Error
}
}
}
同理,如果你确定managedObjectContext.save()
不会throw
和exception
,代码精简为:
func saveContext () {
if managedObjectContext.hasChanges {
try! managedObjectContext.save()
}
}
并推断为什么 managedObjectContext
在 Swift 2 代码中不是可选的,这是因为 NSManagedObject(concurrencyType:)
是一个不会失败的初始化程序。在 Xcode 6 中,如果 NSPersistentStoreCoordinator
为 nil,则样板代码返回一个可选上下文,但您可以通过检查轻松处理此问题。
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
moc.persistentStoreCoordinator = coordinator
return moc
}()