致命错误:在展开可选值错误 Swift 时意外发现 nil

Posted

技术标签:

【中文标题】致命错误:在展开可选值错误 Swift 时意外发现 nil【英文标题】:fatal error: unexpectedly found nil while unwrapping an Optional value error Swift 【发布时间】:2015-11-04 23:47:13 【问题描述】:

在查看所有其他堆栈溢出线程后,我收到了我在标题中写的错误,但没有一个能真正解释问题出在哪里。

当我启动应用程序时,它立即崩溃并以红色突出显示这一行:

let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")!

应用程序启动到的主视图控制器具有以下代码:

import UIKit
import CoreData

class ViewController: UIViewController, UITableViewDataSource 


@IBOutlet weak var tableView: UITableView!
var subjects = [NSManagedObject]()
override func viewDidLoad() 
    super.viewDidLoad()

    tableView.registerClass(UITableViewCell.self,
        forCellReuseIdentifier: "Cell")


func tableView(tableView: UITableView,
    numberOfRowsInSection section: Int) -> Int 
        return subjects.count


func tableView(tableView: UITableView,
    cellForRowAtIndexPath
    indexPath: NSIndexPath) -> UITableViewCell 

        let cell =
        tableView.dequeueReusableCellWithIdentifier("Cell")

        let check = subjects[indexPath.row]

        cell!.textLabel!.text =
            check.valueForKey("name") as? String

        return cell!

override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()



@IBAction func addName(sender: AnyObject) 
    let alert = UIAlertController(title: "New Subject", message: "Add a new Subject", preferredStyle: .Alert)
    let saveAction = UIAlertAction(title: "Save",
        style: .Default,
        handler:  (action:UIAlertAction) -> Void in

            let textField = alert.textFields!.first
            self.saveName(textField!.text!)
            self.tableView.reloadData()
    )


    let cancelAction = UIAlertAction(title: "Cancel",
        style: .Default)  (action: UIAlertAction) -> Void in
    

    alert.addTextFieldWithConfigurationHandler 
        (textField: UITextField) -> Void in
    
    alert.addAction(saveAction)
    alert.addAction(cancelAction)

    presentViewController(alert,
        animated: true,
        completion: nil)

func saveName(name: String) 

    let appDelegate =
    UIApplication.sharedApplication().delegate as! AppDelegate

    let managedContext = appDelegate.managedObjectContext


    let entity =  NSEntityDescription.entityForName("Subjects",
        inManagedObjectContext:managedContext)

    let check = NSManagedObject(entity: entity!,
        insertIntoManagedObjectContext: managedContext)


    check.setValue(name, forKey: "name")


    do 
        try managedContext.save()

        subjects.append(check)
     catch let error as NSError  
        print("Could not save \(error), \(error.userInfo)")
    

override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)


    let appDelegate =
    UIApplication.sharedApplication().delegate as! AppDelegate

    let managedContext = appDelegate.managedObjectContext


    let fetchRequest = NSFetchRequest(entityName: "Subjects")


    do 
        let results =
        try managedContext.executeFetchRequest(fetchRequest)
        subjects = results as! [NSManagedObject]
     catch let error as NSError 
        print("Could not fetch \(error), \(error.userInfo)")
    
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle,forRowAtIndexPath indexPath: NSIndexPath) 

    


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if (segue.identifier == "ShowAssesment") 
        let indexPath = tableView.indexPathForCell((sender as? UITableViewCell)!)
        let listVC = segue.destinationViewController as? AssesmentViewController

        let subject = subjects[indexPath!.row]

        listVC?.assesments = ["Death"]
    




【问题讨论】:

谢谢,这已经奏效,我能够更改它,我遇到的另一个问题是,当我点击一个 segue 时,它​​不会转移到另一个表视图,即使我已使用 ID ShowAssesment 制作了一个秀场 【参考方案1】:

执行let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "mom")!时,没有找到HitList文件,结果为nil。你不能解开 nil。

【讨论】:

【参考方案2】:

您正在尝试解开该行中不存在的值..

let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")!

找到您要获取的文件并确保它存在并且名为 HitList.momd。而是这样做......

var modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")

所以万一文件不存在,您的应用程序不会崩溃。

【讨论】:

【参考方案3】:

Apple 的URLForResource 方法:

返回由指定名称和扩展名标识并位于给定捆绑目录中的资源文件的文件 URL。

然后返回:

资源文件的文件 URL 或 nil 如果找不到文件。如果bundlePath 参数指定的包不存在或不是可读目录,则此方法还返回nil

你需要在解包之前检查它,记住每次你使用! 操作符解包一个你对编译器说变量总是有值的可选,你可以使用可选绑定来修复它,如下所示:

if let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd") 
    // do whatever you what with the value 

else 
   // the value is nil

或者改为使用 Swift 2.0 中的新 guard 语句,如下所示;

guard let let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd") else 
   // the value is nil
   return

希望对你有所帮助。

【讨论】:

【参考方案4】:

谢谢,已经成功了。 John Doe 没有工作,因为它仍然给出错误消息,但在这种情况下将 URLForResource 更改为 xcdatamodeld 名称的名称。

【讨论】:

以上是关于致命错误:在展开可选值错误 Swift 时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章

Swift:致命错误:在展开可选值时意外发现 nil

swift 2 致命错误:在展开可选值时意外发现 nil - 类别名称

Swift 和 UILabel - 致命错误:在展开可选值时意外发现 nil

Swift 错误 - 致命错误:在展开可选值时意外发现 nil [重复]

(Swift) PrepareForSegue: 致命错误: 在展开可选值时意外发现 nil

致命错误:在展开可选值错误 Swift 时意外发现 nil