Swift 2在appDelegate中迁移saveContext()

kal*_*fun 21 swift swift2

我刚下载了新的Xcode 7.0测试版,并从Swift 1.2迁移到Swift 2.迁移显然没有改变整个代码,实际上是一个方法saveContext(),直到抛出2行错误:

if moc.hasChanges && !moc.save() {
Run Code Online (Sandbox Code Playgroud)

二元运算符'&&'不能应用于两个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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有关如何使其工作的任何想法?

Mic*_*lum 33

您提供的两个错误中的第一个是误导性的,但第二个是现场错误.问题是,!moc.save()从Swift 2开始,不再返回Bool而是注释throws.这意味着您必须使用try此方法以及catch它可能发出的任何异常,而不仅仅是检查它的返回值是true还是false.

为了反映这一点,使用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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ian*_*Ian 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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最好的做法是使用var,error如果你只是这样使用它仍然可用:

func saveContext () {
        if managedObjectContext.hasChanges {
            do {
                try managedObjectContext.save()
            } catch {
                NSLog("Unresolved error \(error), \(error.userInfo)")
                // Handle Error
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

以同样的方式,如果你是肯定managedObjectContext.save()不会throwexception,代码精简下来到:

func saveContext () {
     if managedObjectContext.hasChanges {
        try! managedObjectContext.save()
     }
}
Run Code Online (Sandbox Code Playgroud)

并且为了解释为什么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
}()
Run Code Online (Sandbox Code Playgroud)