首页 文章

如何防止致命错误:意外地发现nil wile unwrapping一个Optional值

提问于
浏览
-1

所以我是核心数据的新手,开始做一些教程,并得到一个非常基本的设置,从AppDelegate保存10分,并且工作正常(能够从控制台获取和打印) .

然后,当我想在另一个VC中使用fetchrequest来检索已成功保存的数据时,我收到以下错误:致命错误:在展开Optional值时意外发现nil . 这是检索数据的代码:

import Foundation
import CoreData
import UIKit


class testVC: UIViewController {
var managedObjectContext: NSManagedObjectContext!
var scores = [Scores]()

@IBOutlet weak var retrieveDataLabel: UIButton!
@IBOutlet weak var saveLabel: UIButton!
  override func viewDidLoad() {
    super.viewDidLoad()

     }


@IBAction func retrieveData(sender: AnyObject) {
    let fetchRequest = NSFetchRequest(entityName: "Scores")
    do {
        if let results = try managedObjectContext.executeFetchRequest(fetchRequest) as? [Scores]{
            scores = results
            for result in results {
                if let gameScore = result.valueForKey("gameScore") as? Int{
                    print("Your score is \(gameScore)")
                }
            }
        }
    }catch{
        print("Error fetching data")
    }}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

因为我正在使用如果让..我不应该得到“获取数据时出错”?而不是致命的错误?为什么我在加载应用程序时可以检索数据,但是当我尝试使用相同的代码检索不同VC中的数据时却无法检索数据?

我已经查看了在解开可选值时发现的与致命错误有关的其他问题:What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?

fatal error: unexpectedly found nil while unwrapping an Optional value似乎我在那里,但确实保存了数据,我可以在启动应用程序时在控制台中检索它 . 使用相同的获取请求我不是这样的 .

我在这里错过了什么?感觉它应该是非常基本的,但由于某种原因,在尝试2天后才能让它工作 .

app委托代码来保存和检索数据:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    //addTestData()
    let fetchRequest = NSFetchRequest(entityName: "Scores")
    do {
        if let results = try managedObjectContext.executeFetchRequest(fetchRequest) as? [NSManagedObject]{
            for result in results {
                if let gameScore = result.valueForKey("gameScore") as? Int{
                    print("Your score is  \(gameScore)")
                }
            }
        }
    }catch{
        print("Error fetching data")
    }

    return true
}
func addTestData(){

    guard let entity = NSEntityDescription.entityForName("Scores", inManagedObjectContext: managedObjectContext) else{
        fatalError("Could not find entity description")
    }
    for i in 1...10{
        let score = Scores(entity: entity, insertIntoManagedObjectContext: managedObjectContext)
        score.gameScore = i
    }
    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()
    }

}

任何帮助将不胜感激!

3 回答

  • 0

    问题是 nil NSManagedObjectContext (声明但没有值)

    根据定义 executeFetchRequest 成功返回一个非可选数组,因为您应该从Core Data模型知道实体 Scores 总是返回 Scores 对象,您可以安全地写

    do {
        scores = try managedObjectContext.executeFetchRequest(fetchRequest) as! [Scores]
    

    显然,使用 NSManagedObject 子类直接使用该属性来避免类型转换 . 仅当属性 gameScore 声明为可选时,才需要可选绑定 .

    for result in results {
            if let gameScore = result.gameScore {
                print("Your score is \(gameScore)")
            }
    

    但是对于像分数这样的 Int 值,非可选的更合理,而不是将代码减少到

    for result in results {
           print("Your score is \(result.gameScore)")
        }
    
  • 1

    当你使用if时,你正在检查是否可以将结果作为Int . 您想先查看该结果是否存在 . 试试这个:

    for result in results {
                if let gameScore = result.valueForKey("gameScore") {
                    print("Your score is \(gameScore as! Int)")
                }
            }
    
  • 0

    所以我确实设法让它工作,使用以下for managedObjectContext:let managedContext = AppDelegate() . managedObjectContext

    我仍然感到困惑,为什么我没有得到捕获中指定的错误,但至少它现在正在工作 .

    谢谢你的回答!

相关问题