我刚刚下载了新的Xcode 7.0测试版,并从Swift 1.2迁移到Swift 2.迁移显然没有改变整个代码,实际上是一个方法saveContext(),直到抛出2行错误才行:
if moc.hasChanges && !moc.save() {
二元运算符'&&'不能应用于两个Bool操作数
和
调用可以抛出,但没有标记为'try'并且未处理错误
方法如下:
// 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()
}
}
}
关于如何使其发挥作用的任何想法?
答案 0 :(得分:33)
您提供的两个错误中的第一个是误导性的,但第二个是现场错误。问题出在!moc.save()
,从Swift 2开始,不再返回Bool,而是注释throws
。这意味着您必须try
此方法和catch
它可能发出的任何异常,而不仅仅是检查其返回值是真还是假。
为了反映这一点,使用Core Data在Xcode 7中创建的新项目将生成以下样板代码,该代码可以替换您正在使用的代码。
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()
}
}
}
答案 1 :(得分:9)
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
}()