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 的相关文章

  • 在 Swift 中将进程标准输出重定向到 Apple 系统日志工具

    我正在为 macOS 构建一个启动子进程的 Swift 应用程序 该子进程将有用的信息记录到stdout 我在 Xcode 控制台中看到它 我现在想要实现的是重定向子流程stdout到Apple Log Facility 以便我们可以在部署
  • 仅当捏住单元格的 imageView 时,才可以在 UICollectionView 的自定义单元格中放大/缩小 UIImageView 吗?

    我有一个 CollectionView 它有一个自定义单元格 我想放大 缩小单元格中的 imageView 所以我在 CollectionView m 添加捏合手势 当我向 self collectionView 添加手势时 如下所示 se
  • 场景 - 根据 iPad 或 iPhone 使用专用故事板

    Apple 现在希望我们使用 场景 而不是窗口和屏幕来显示 iPad 和 iPhone 的内容 现在添加了对场景的支持 我似乎失去了使用故事板定位 iPad 或 iPhone 的能力 I set my scenes inside plist
  • 读取目标设备上 UIAutomation 的 UIAApplication.setPreferencesValueForKey() 设置的首选项?

    在过去的几天里 我一直在使用 Apple 的 UIAutomation 框架 试图组合一套验收测试来推动我正在开发的应用程序的开发 以 BDD 类型的方式 我遇到的一件事是如何让 SUT 进入给定状态 以便在我需要设置一些内部状态时可以开始
  • Cordova 插件不适用于 Ionic

    我正在 Angular 中构建一个 Ionic 应用程序 但一直无法让插件工作 例如 我尝试使用状态栏插件 如下所述 http ionicframework com tutorials fullscreen apps http ionicf
  • iOS 12.1 上的 UITabBar 项目在返回导航上跳跃

    我有一个 iOS 应用程序UITabBarController在主屏幕上 导航到隐藏的详细信息屏幕UITabBarController有设置hidesBottomBarWhenPushed true 返回主屏幕时UITabBarContro
  • detached 和 allocateCurrentContext 是什么意思?

    当我将作业添加到队列中时 DispatchWorkItemFlags 为我们提供了几个选项可供选择 public func sync
  • 获取经典蓝牙连接设备列表(无BLE)[EAAccessoryManager]

    我需要制作一个应用程序 能够判断我当前是否连接到经典蓝牙设备 实际上 它将是蓝牙汽车设备 我的第一步是了解当前连接的经典蓝牙设备是什么 我无法使用 CoreBluetooth 因为它仅适用于 LE 我尝试使用外部附件框架 这是代码 一个按钮
  • Vapor MySQL - 未显示为导入值

    这个问题是关于 Swift Web 框架 Vapor 我正在尝试使用 Swift 的包管理器导入 VaporMySQL 框架 我已经在本地运行数据库 mySQL 端口打开并工作 mySQL 数据库正在工作 Vapor 应用程序正在工作 我已
  • webapp 在 iOS 7 中无法正确缩放

    有人遇到同样的问题吗 content width device width 当我的 iphone 仍然是 i0S 6 并且我刚刚更新到 iOS 7 并且似乎不再工作时它就可以工作 或者可能是其他原因导致了问题 有人有什么想法吗 现在我正在使
  • 如何测试包含应用程序是否授予“允许完全访问”权限?

    我正在开发一个键盘扩展项目 在应用程序代码的某些点 我需要测试用户是否已授予键盘扩展的 允许完全访问 权限 协议是我需要从应用程序端进行这些测试 并在此基础上让用户访问键盘设置或在未授予权限的情况下提醒他 问题是这里提供的方法如下 func
  • iOS:不明确的属性合成行为。继承相关

    我在用着AppCode它标记了一个非常大的项目代码中的一个有趣的情况 预ARC 子类定义并合成一个称为委托的属性 实际上属性声明已经被注释掉了 但是 synthesize delegate delegate 声明被留下了 该代码可以编译 大
  • Xcode 6 自适应故事板每个设备有不同的 Segues

    我对 Xcode 6 中新引入的自适应故事板遇到了一些麻烦 iPhone 应用程序已经完成 现在我想用它创建一个通用应用程序 假设我有一个viewcontroller显示一些单元格和详细信息viewcontroller其中显示单元格的详细信
  • 找不到“folly/Portability.h”文件 React 库

    我的 React Native 项目在 Xcode 上遇到构建失败 错误是 folly Portability h file not found 在过去的几天里 我一直在尝试自己解决这个问题 但无法解决 RN info React Nati
  • 使用 swift 在 WKWebView 上显示活动指示器

    我正在处理以下代码 并尝试在页面加载时在视图中显示活动指示器 我尝试实施WKNavigationDelegate方法 但我失败了 因为没有任何显示 对于如何解决这个问题 有任何的建议吗 我没有设置 SupportWebView 视图dele
  • 如何为现有核心数据实体添加更多属性?

    我有一个正在使用核心数据的项目 我需要向现有实体 列 添加更多属性 列 如果我手动将属性添加到数据模型应用程序崩溃 这是由于我用来将数据插入表的上下文保存之前 请帮助 谢谢 所以我的问题是我不知道这个持久存储协调器代码去了哪里 事实证明它是
  • 可以在 iOS 应用程序中全局禁用旋转吗?

    我有一个由很多视图控制器组成的应用程序 在项目摘要中 我已将纵向方向设置为唯一支持的设备方向 然而 该应用程序在横向旋转时仍然会变得混乱 我的问题是 有没有办法通过应用程序委托或其他方式全局禁用自动旋转 或者我是否必须进入所有视图控制器并添
  • UISlider 可捕捉到固定的步数(如 iOS 7 设置应用中的文本大小)

    我正在尝试创建一个UISlider让您可以从一组数字中进行选择 每个滑块位置应等距 并且滑块应卡入每个位置 而不是在它们之间平滑滑动 这是滑块的行为Settings gt General gt Text Size 这是在 iOS 7 中引入
  • iPhone 拒绝了发布请求 未说明

    iPhone 拒绝了发布请求 内部启动错误 进程启动失败 未指定 这个错误让我抓狂 我似乎无法解决它 我从发现的所有地方都做了以下操作 刷新证书 注销并进入开发者苹果帐户 下载手动证书 删除 Apple 全球证书 重新启动 Mac 和 iP
  • 如何更改 UIImage 的颜色? [复制]

    这个问题在这里已经有答案了 我不想改变图像的背景颜色 而是改变整个图像的颜色 但问题是 我只能改变backgroundColor 接受的答案是正确的 但还有更多easy way for UIImageView Obj C UIImage i

随机推荐

  • 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