4

我观看了 WWDC 会议,阅读了有关 Swift 的新程序员书籍,并阅读了我能找到的有关 Stack Overflow 的所有相关问题。从 Swift 1.2 迁移到 Swift 2.0 后,我修复了我的应用程序中的大多数错误。

但是,仍有一些我没有设法解决。

向下转换 AnyObject

错误:

无法从“[AnyObject]”向下转换为更可选的类型“[NSManagedObject]”

代码:

    let fetchRequest = NSFetchRequest(entityName: formulaEntity)
    
    var error: NSError?
    
    do {
        let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]?
        
        if let results = fetchedResults {
            stocks = results
        } else {
            print("Could not fetch \(error), \(error!.userInfo)")
        }
    } catch {
        print("ERROR: \(error)")
    }

显示的错误发生在该let fetchedResults = try...行中

我遇到的另一个奇怪错误是在我的 AppDelegate 中:

错误:

'NSMutableDictionary' 不能转换为 '[NSObject : AnyObject]'

代码:

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("Stocks.sqlite")
    var error: NSError? = nil
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
    } catch var error1 as NSError {
        error = error1
        coordinator = nil
        // Report any error we got.
        let dict = NSMutableDictionary()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason
        dict[NSUnderlyingErrorKey] = error
        error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as [NSObject : AnyObject])
        // Replace this 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()
    } catch {
        fatalError()
    }
    
    return coordinator
}()

我从来没有接触过上面的代码。所以我不知道为什么苹果的迁移工具没有正确迁移它。

我的 AppDelegate 中的另一个错误:

二元运算符 '&&' 不能应用于两个 Bool 操作数

调用可以抛出,但它没有标记'try'并且错误没有被处理。

代码:

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

同样,我还没有触及 AppDelegate 的这一部分,并且不确定上面的代码到底有什么问题。

4

2 回答 2

9

AppDelegate 上的 CoreData 似乎存在严重的 Swift 2 迁移问题。我能够通过将 AppDelegate CoreData Swift 1.2 完全替换为 Swift 2.0 来解决这个问题。

您需要做的是删除以下内容

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {

lazy var managedObjectContext: NSManagedObjectContext = {

// MARK: - Core Data Saving support

func saveContext ()

并粘贴 Swift 2.0 代码:

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this 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 \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }

    return coordinator
}()

lazy var managedObjectContext: NSManagedObjectContext = {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
    let coordinator = self.persistentStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()

// MARK: - Core Data Saving support

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

这应该可以解决问题。

于 2015-10-11T14:01:09.850 回答
4

无法从“[AnyObject]”向下转换为更可选的类型“[NSManagedObject]”

在 Swift 1.2 中,executeFetchRequest(:_)返回[AnyObject]?. 在 Swift 2 中,它返回[AnyObject]是因为 new try… 语法返回一个非可选的。

(在方法返回的情况下,该nil方法根本不会返回,并且控制将移动到catch块。)


'NSMutableDictionary' 不能转换为 '[NSObject : AnyObject]'

这意味着您正在尝试将某些内容插入到NSMutableDictionary无法转换为 Objective-C 对象的内容中。在您的情况下,我认为这是因为error是一个符合 struct 的结构ErrorType,而不是一个NSError对象。尝试添加error1


调用可以抛出,但它没有标记'try'并且错误没有被处理。

save()可能会抛出一个错误,因此它需要与 一起执行try,而不是被评估为bool. 正如 Martin R. 在评论中指出的那样,这个问题的答案提供了一个完整的解决方案,所以我不会在这里重复它。

于 2015-06-13T23:02:19.747 回答