iOS 8 核心数据堆栈 - 致命错误:在解包可选值时发现 nil

2024-04-24

我对 iOS 开发比较陌生,决定实现自己的 Core Data 堆栈,替换 Apple 的默认堆栈。

我必须对我的代码进行更改(显然)并且能够弄清楚它,但在这种情况下我不能。这是我的代码:

import UIKit
import CoreData

class AddTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var nameTextField:UITextField!
    @IBOutlet weak var locationTextField:UITextField!
    @IBOutlet weak var imageView:UIImageView!
    @IBOutlet weak var notesView:UITextView!

    var coreDataStack = (UIApplication.sharedApplication().delegate as AppDelegate).coreDataStack

    var backpackerSpot:BackpackerSpot!
    var managedContext: NSManagedObjectContext!

    override func viewDidLoad() {
        super.viewDidLoad()

    }

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

    // TODO Give user the choice of the Photo Library or the Camera
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if indexPath.row == 0 {
            if UIImagePickerController.isSourceTypeAvailable(.Camera) {
                let imagePicker = UIImagePickerController()
                imagePicker.allowsEditing = false
                imagePicker.delegate = self
                imagePicker.sourceType = .Camera

                self.presentViewController(imagePicker, animated: true, completion: nil)
            }
        }

        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }

    // FIXME image is being displayed in landscape if it is taken in portrait mode by default
    func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
        imageView.image = image
        imageView.contentMode = UIViewContentMode.ScaleAspectFill
        imageView.clipsToBounds = true

        dismissViewControllerAnimated(true, completion: nil)
    }

    @IBAction func save() {

        //validation
        var errorField = ""

        // TODO have placeholder text in the NOTES field match up with the placholder text in the NAME and LOCATION fields.
        if nameTextField.text == "" {
            errorField = "name"
        } else if locationTextField.text == "" {
            errorField = "location"
        } else if notesView.text == "" {
            errorField = "notes"
        }

        if errorField != "" {

            let alertController = UIAlertController(title: "Error", message: "You must fill in \(errorField).", preferredStyle: .Alert)
            let doneAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
            alertController.addAction(doneAction)

            self.presentViewController(alertController, animated: true, completion: nil)

            return
        }

        // If all fields are correctly filled in, extract the field value
        // Create Restaurant Object and save to data store
//        if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).coreDataStack.context {

            let entityBackpackerSpot = NSEntityDescription.entityForName("BackpackerSpot", inManagedObjectContext: coreDataStack.context)

            backpackerSpot?.spotName = nameTextField.text
            backpackerSpot?.spotLocation = locationTextField.text
            backpackerSpot?.spotImage = UIImagePNGRepresentation(imageView.image)
            backpackerSpot?.spotNote = notesView.text

            var error: NSError?
            if !managedContext.save(&error) {
                println("insert error: \(error!.localizedDescription)")
                return
            }
        // Execute the unwind segue and go back to the home screen
        performSegueWithIdentifier("unwindToHomeScreen", sender: self)
    }

}

该应用程序启动正常,但当我单击附加到保存功能的 UIButton 时,它崩溃并出现以下错误:

fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)

调试器突出显示的行是:

  if !managedContext.save(&error) {

不可否认,我必须花更多的时间在 Swift 中使用可选值,因为它们似乎经常给我带来麻烦,尽管通常我能够解决它。如果有人能指出我正确的方向,那就太好了。谢谢。

编辑:这是我的核心数据堆栈:

import Foundation
import CoreData

class CoreDataStack {

    let model: NSManagedObjectModel
    let storeCoordinator: NSPersistentStoreCoordinator
    let context: NSManagedObjectContext
    let store: NSPersistentStore?

    let dbName = "BackpackerSpots"
    // these options do the migration for us
    let options = [NSInferMappingModelAutomaticallyOption:true,
        NSMigratePersistentStoresAutomaticallyOption: true]

    init() {

        //1 loading model from the file
        let bundle = NSBundle.mainBundle()
        let modelURL = bundle.URLForResource(dbName, withExtension: "momd")
        model = NSManagedObjectModel(contentsOfURL: modelURL!)!

        //2 store coordinator created using that model
        storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model)

        //3 context
        context = NSManagedObjectContext()
        context.persistentStoreCoordinator = storeCoordinator

        //4. store
        let documentsURL = MyDocumentDirectory()
        let storeURL = documentsURL.URLByAppendingPathComponent(dbName)

        var error:NSError?

        store = storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType,
            configuration: nil,
            URL: storeURL,
            options: nil,
            error: &error)

        if store == nil {
            println("error adding persistent store: \(error)")
            abort()
        }
    }

    func saveContext() {
        var error: NSError?

        if context.hasChanges && !context.save(&error) {
            println("Could not save. \(error), \(error?.description)")
        }
    }

}

编辑:这是我的根视图控制器:

import UIKit
import CoreData

class BackpackerSpotTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {

    var coreDataStack = (UIApplication.sharedApplication().delegate as AppDelegate).coreDataStack

//    var backpackerSpot:BackpackerSpot!
    var managedContext: NSManagedObjectContext!

    var backpackerSpots:[BackpackerSpot] = []

    var fetchResultController:NSFetchedResultsController!

    // Let's add some animations!
    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        // initial cell state
        cell.alpha = 0

        // state after animations
        UIView.animateWithDuration(1.0, animations: { cell.alpha = 1})
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        var fetchRequest = NSFetchRequest(entityName: "BackpackerSpot")
        let sortDescriptor = NSSortDescriptor(key: "spotName", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]

//        if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).coreDataStack {

        let entityBackpackerSpot = NSEntityDescription.entityForName("BackpackerSpot", inManagedObjectContext: coreDataStack.context)

            fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil)
            fetchResultController.delegate = self

            var error: NSError?

            var result = fetchResultController.performFetch(&error)
            backpackerSpots = fetchResultController.fetchedObjects as [BackpackerSpot]

            if result != true {
                println(error?.localizedDescription)
            }
        }





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

    // MARK: - Table view data source

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.backpackerSpots.count
    }


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

        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell


        let backpackerSpot = backpackerSpots[indexPath.row]
        cell.nameLabel.text = backpackerSpot.spotName
        cell.thumbnailImageView.image = UIImage(data: backpackerSpot.spotImage)
        cell.locationLabel.text = backpackerSpot.spotLocation


        return cell
    }

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {


    }


    override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {


        var deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete",handler: {
            (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in


//            if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext {
           let entityBackpackerSpot = NSEntityDescription.entityForName("BackpackerSpot", inManagedObjectContext: self.coreDataStack.context)

                let backpackerSpotToDelete = self.fetchResultController.objectAtIndexPath(indexPath) as BackpackerSpot
                self.managedContext.deleteObject(backpackerSpotToDelete)

                var error: NSError?
                if !self.managedContext.save(&error) {
                    println("Could not save \(error), \(error?.description)")
                }


        })
        deleteAction.backgroundColor = UIColor(red: 169.0/255.0, green: 37.0/255.0, blue:
            50.0/255.0, alpha: 1.0)
        return [deleteAction]
    }

    func controllerWillChangeContent(controller: NSFetchedResultsController!) {
        tableView.beginUpdates()
    }

    func controller(controller: NSFetchedResultsController!, didChangeObject anObject: AnyObject!, atIndexPath indexPath: NSIndexPath!, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath!) {

        switch type {
        case .Insert:
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
        case .Delete:
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        case .Update:
            tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

        default:
            tableView.reloadData()
        }

        backpackerSpots = controller.fetchedObjects as [BackpackerSpot]
    }

    func controllerDidChangeContent(controller: NSFetchedResultsController!) {
        tableView.endUpdates()
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if segue.identifier == "showBackpackerSpotDetails" {
            if let row = tableView.indexPathForSelectedRow()?.row {
                let destinationController = segue.destinationViewController as DetailViewController
                destinationController.backpackerSpot = backpackerSpots[row]
            }
        }
    }

    @IBAction func unwindToHomeScreen(segue: UIStoryboardSegue) {

    }

}

你还没有初始化你的NSManagedContext多变的。使用默认的核心数据设置,您可以执行以下操作:

 override func viewDidLoad() {
      if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
          managedContext = appDelegate.managedObjectContext
      }
 }

编辑:鉴于您的核心数据设置,您应该这样做:

 override func viewDidLoad() {
      managedContext = coreDataStack.context
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 8 核心数据堆栈 - 致命错误:在解包可选值时发现 nil 的相关文章

  • ios 用户如何取消 Facebook 登录?

    当用户到达此屏幕时 无法取消 我能做些什么 为了首先获得这个视图 我正在运行 NSMutableDictionary params NSMutableDictionary dictionaryWithObjectsAndKeys vid l
  • 从 UIImagePickerController 相机视图推送 viewController

    我正在开发一款消息应用程序 类似于 WhatsApp 用户可以互相发送文本和图像消息 当用户想要发送图像时 他可以从相机胶卷中选择一张图像 也可以用相机拍摄一张图像 这就是我介绍的方式UIImagePickerController对于这两种
  • UIButton 导致无法识别的选择器发送到实例

    我正在尝试使用 for 循环创建多个按钮 但在使用 sender 函数时遇到问题 我有以下代码 func setUpButtons for i in 1 3 let btn UIButton UIButton frame CGRect x
  • 如何在 SwiftUI 中仅使用 ForEach 而不是列表来滑动删除

    我正在 SwiftUI 中使用 ForEach 制作自定义列表 我的目标是进行滑动删除手势 而不是将 ForEach 嵌入到列表中 到目前为止 这是我的代码 import SwiftUI struct ContentView View le
  • 如何在 Core Data 中存储图像?

    只是猜测 我创建一个属性并将其类型设置为 二进制 但最终我该如何使用它呢 我猜幕后有一个 NSData 那么该属性实际上采用 NSData 吗 这个问题已经被问过很多次了 答案有点复杂 当涉及二进制数据时 您应该根据要使用的数据的预期大小来
  • 在横向中自动调整 UITableCells 内容的大小

    在 UITableView 中 我通过 UILabels 将内容添加到单元格中 定义最佳尺寸 与单元格宽度允许的一样大 我注意到只有tableView contentSize width是可靠的 因为cell contentView bou
  • 如何在 iOS 9 上可靠地检测是否连接了外部键盘?

    在 iOS 9 之前 确定是否连接外部键盘的最可靠方法是监听UIKeyboardWillShowNotification并使文本字段成为第一响应者 如中所述这个问题 https stackoverflow com questions 289
  • 当地图视图只是屏幕的一部分时,如何在 iOS 模拟器中进行捏合?

    我在 iPad 上有一个视图 我正在添加MKMapView也就是说 全屏高度的一半 然而 当我尝试在 iOS 模拟器上进行捏合时 它不起作用 因为 to nubs 填充了模拟器上的整个 iPad 视图 And so with the map
  • 是否可以使用 Firebase 安排推送通知? [复制]

    这个问题在这里已经有答案了 我已经阅读了我能找到的所有文档 但仍然不知道这是否可行 如果我是用户 我可以安排特定时间的推送通知吗 Example 1 我是用户并打开应用程序 2 我允许通知并转到 pickerView 或其他任何内容 并设置
  • 在 Xcode 5 中重命名 iOS 项目[重复]

    这个问题在这里已经有答案了 我需要重命名一个 iOS 项目 有没有办法在不开始一个全新项目的情况下做到这一点 我发现的所有其他信息都与 Xcode 4 或旧版本相关 这些方法似乎使项目崩溃 我在尝试任何名称更改之前创建了一个快照 在 Xco
  • 在 iOS 上将 NSString 转换为 NSDate 的正确方法?

    我一直在使用此方法将常规 NSString 对象转换为 NSDate 但尝试向 Apple 提交更新 但遭到拒绝 在 iOS 中还有什么其他方法可以做到这一点 NSString date str 2011 08 12T12 20 00Z N
  • UIButton的高亮状态由什么控制事件开始和结束

    我正在创建类似钢琴的视图UIButton作为钢琴键 什么UIControlEvents当按钮获得和失去突出显示状态时 我应该监听以获得回调吗 我试图创建子类UIButton并添加属性观察者highlighted并且运行良好 然而 有时我需要
  • 覆盖层不与 UITableView 一起滚动 - iOS

    我有一个 UITableView 类 它使用以下方法在转到下一个屏幕时调用加载覆盖 问题是这个加载屏幕不随列表滚动 所以如果你滚动一点并单击某些东西 加载屏幕不会显示 因为它位于顶部 如何让加载屏幕始终保持在 UITableView 的顶部
  • 如何使用 Swift 使用 TouchID?

    Apple 为 iOS 8 的 TouchID 实现提供的文档采用 Objective C 语言 有 Swift 版本吗 Objective C IBAction touchIDAvailable UIButton touchIDAvail
  • Swift:使具有相同“形状”的两种类型符合通用协议

    我有两种不同的类型 它们代表相同的数据 并且具有完全相同的 形状 这两种不同的类型是代码生成的 我被迫处理它们 但是 我想让它们符合一个通用的协议 这样我就可以对这两种类型一视同仁 这是一个例子 假设这是我所坚持的两种代码生成类型 stru
  • ios水平居中约束问题?

    I am having hard time in learning constraints auto layout in iOS I have used any width any height I have a storyboard sc
  • 水平 UICollectionView 单行布局

    我正在尝试使用以下命令设置简单的水平布局UICollectionView 兜圈子却没有达到预期的结果 所以任何指针或例子将不胜感激 我粘贴经常更改的代码但没有成功可能没什么意义 该图像显示两行 第一行是单个项目 尺寸正确并且在中心正确对齐
  • UIImageJPEGRepresentation 在视网膜显示屏上提供 2x 图像

    我有这段代码 它创建一个图像 然后向其添加一些效果并缩小其大小以使其largeThumbnail UIImage originalImage UIImage imageWithData self originalImage thumbnai
  • Xcode 8 / Swift 3:“UIViewController 类型的表达式?未使用”警告

    我有以下函数 它之前编译得很干净 但在 Xcode 8 中生成警告 func exitViewController navigationController popViewController animated true UIViewCon
  • SwiftUI:发送电子邮件

    在正常情况下UIViewController在 Swift 中 我使用此代码发送邮件 let mailComposeViewController configuredMailComposeViewController mailCompose

随机推荐

  • Django QuerySet 何时被评估?

    我读过 django 查询集是懒惰的 但这是否意味着懒惰 因为我可以在一个语句上链接多个操作 或者懒惰 因为查询被延迟到需要结果的时候 例如 以下模拟代码是否执行两个或三个 SQL 查询 query Books objects filter
  • StreamWriter.Flush() 和 StreamWriter.Close() 有什么区别?

    两者在功能上有什么区别StreamWriter Flush and StreamWriter Close 当我的数据没有正确写入文件时 我添加了两个Flush and Close 到我的代码的末尾 然而 我意识到添加either Flush
  • 具有来自包含器类的静态方法调用的 Ruby 模块

    我需要在模块中定义使用包含该模块的类中的方法的常量 module B def self included base class lt lt base CONST self find end end end class A def self
  • 如何确保以编程方式发送的电子邮件不会被自动标记为垃圾邮件?

    这是一个棘手的问题 我一直依赖技术 例如基于许可的电子邮件 即仅发送给您有权发送的人 而不是公然使用spamish术语 最近 我以编程方式发送的一些电子邮件开始被自动混入人们的垃圾邮件文件夹中 我想知道我能对此做些什么 尽管这些特定的电子邮
  • 为什么空 python 正则表达式搜索的返回值是匹配的?

    将空字符串传递给正则表达式对象时 搜索结果是匹配对象而不是 None 因为没有任何东西可以匹配 所以它应该是 None 吗 import re m re search some text if m is None print Returne
  • 从新线程更新 JProgressBar

    如何从另一个线程更新 JProgressBar setValue int 我的第二个目标是用尽可能少的课程来完成它 这是我现在的代码 Part of the main class pp addActionListener new Actio
  • 在 F# 中组合谓词

    F 中是否有逻辑组合谓词的标准方法 例如 假设我有isCar x and isBlue x然后我想要一些能给我的东西 let isBlueCar x isCar x isBlue x 但是使用某种组合而不是调用 可能像 let isBlue
  • 扫描大量BLE标签

    我一直在寻找在一次扫描中扫描大量 BLE 标签 StickNFind 的可能性 我注意到 当我扫描 10 秒时 我可以轻松检测到大约 20 个 BLE 当我将扫描间隔增加到 30 秒左右并尝试扫描大量 BLE 标签时 例如200 个标签 我
  • WPF:无法控制键盘焦点

    这周我遇到了一个让我陷入困境的问题 总而言之 问题是当我左键单击另一个控件时 我无法从代码中将键盘焦点赋予 ComboBox 具体来说 我有一个 CustomControll 它有一个 Scrollview 其中包含另一个 CustomCo
  • 与使用类相比,在 Program.cs/main 中编写代码是否有充分的理由? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在开发一个相当大的应用程序 而我的技术主管和我在某些事情上的看法并不一致 其中之一是关于控制台应用程序 这些应用程序正在从 shell 脚本移植到
  • 无法在我的 Maven 项目中使用依赖项 jboss-javaee-6.0

    我已经使用 JBoss 7 1 1 设置了一个 Maven 项目 我想使用 JavaEE 库 在根 pom xml 中我设置了
  • 实体框架:唯一(非主键)父字段上的复合外键

    我有一个表需要通过其绑定到另一个表Id列 并按其第三个表 Id Code 列 我可以轻松地做SQL服务器同时使用主键和唯一索引 但不知道如何实现它实体框架 如果我把 Key 两列上的属性 那么我无法创建第一个关系 否则 如果我只申请一个 K
  • 适用于 Windows 的二进制 python 包(模块)的无人值守安装

    是否没有合理的方法来执行 Windows 二进制 python 包的脚本安装 不幸的是 似乎几个基本的 Windows python 软件包 如 pywin32 和 py2exe 只能以 EXE 形式提供 而不是以 MSI 形式提供 据我所
  • fopen() 在 Linux 上创建文件失败

    我正在尝试通过创建一个文件fopen 如下 但不创建该文件并让我 Can t create file P S 我在 Linux Ubuntu 上使用 LAMP 服务器 在创建该文件之前我已经尝试过以下命令 sudo chmod R 755
  • 陷入状态 Monad

    我想使用节点和唯一键的 IntMap 创建一个图形结构 这个话题已经被很好地涵盖了here https stackoverflow com questions 12941625 ids from state monad in haskell
  • python sqlite3更新不更新

    问题 为什么这个sqlite3语句没有更新记录 Info cur execute UPDATE workunits SET Completed 1 AND Returns WHERE PID AND Args pickle dumps Re
  • sql server 存储过程首次运行缓慢

    我有一个存储过程 每天在午夜过后运行九次 它不是一个理想的存储过程 但您知道它是怎样的 没有任何计划能够与现实接触 此存储过程通常需要大约一分钟的时间来运行 根据其处理的数据量给出或花费一些时间 然而 在给定早晨的第一次运行中 有时会花费大
  • PHP XML - 在特定位置插入 XML 节点

    我想在 XML 文件中的特定位置插入一个带有子节点的节点 我该怎么做 例如 如果我有一个像这样的 XML
  • 使用 strcpy_s 作为 TCHAR 指针(Microsoft 特定)

    我想知道哪个是正确的方法 tcscpy tchar pointer tcslen tchar pointer T Hello World or tcscpy tchar pointer tcsclen tchar pointer T Hel
  • iOS 8 核心数据堆栈 - 致命错误:在解包可选值时发现 nil

    我对 iOS 开发比较陌生 决定实现自己的 Core Data 堆栈 替换 Apple 的默认堆栈 我必须对我的代码进行更改 显然 并且能够弄清楚它 但在这种情况下我不能 这是我的代码 import UIKit import CoreDat