【问题标题】:Swift 2 migration saveContext() in appDelegateappDelegate 中的 Swift 2 迁移 saveContext()
【发布时间】:2015-06-09 10:06:11
【问题描述】:

我刚刚下载了新的 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()
        }
    }
}

关于如何让它工作的任何想法?

【问题讨论】:

    标签: swift swift2


    【解决方案1】:

    您提供的两个错误中的第一个具有误导性,但第二个是正确的。问题出在!moc.save() 中,从 Swift 2 开始,它不再返回 Bool,而是注释为 throws。这意味着你必须try 这个方法和catch 它可能发出的任何异常,而不是仅仅检查它的返回值是真还是假。

    为了反映这一点,在 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()
            }
        }
    }
    

    【讨论】:

    • 谢谢你,这是正确的答案,另外,你需要在 managedObjectContext 之后添加一个!,所以该行看起来像:if managedObjectContext!.hasChanges {try managedObjectContext!.save()
    • @kalafun 不,在 Xcode 7 中 managedObjectContext 不是可选的。将发布我的答案的更新
    • 这很奇怪,我使用的是 xcode 7 beta,由于缺少感叹号而引发错误。等待你的更新..
    • @kalafun 问题是您仍在使用在较低版本的 Xcode 中生成的lazy var managedObjectContext。在 Xcode 7 中,这个属性被生成为非可选的。
    【解决方案2】:

    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() 不会throwexception,则代码会精简为:

    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
    }()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      • 2019-01-17
      • 1970-01-01
      相关资源
      最近更新 更多