无法将数据传递给我的第二个视图控制器

时间:2017-05-18 05:37:07

标签: ios swift core-data segue

尝试传递从CoreData调用的数据时,返回的错误显示线程1:EXC_BAD_INSTRUCTION(代码= EXC_i386_INVOP,子代码= 0x0)。调试器读取

  

致命错误:在解包可选值时意外发现nil

但是,当我在将变量分配给文本字段之前添加print语句时,变量会正确打印出来。我迷失了。任何帮助,将不胜感激。

EEx.eval_string

编辑: 应用Rinki的建议后,Xcode给了我以下更正,并在运行时仍然返回相同的错误。

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          let myVC = storyboard?.instantiateViewController(withIdentifier: "editInventoryItem") as! AddInventoryItemVC
          var inventoryItemName: String = ""
          var inventoryItemStock: Double = 0.0
          var inventoryItemPG: Double = 0.0
          var inventoryItemVG: Double = 0.0
          let itemName = flavors[indexPath.row]

          let appDelegate = UIApplication.shared.delegate as! AppDelegate
          let context = appDelegate.persistentContainer.viewContext
          let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Inventory")

          request.predicate = NSPredicate(format: "inventoryItemName ==%@", itemName)
          if let result = try? context.fetch(request) {
              for object in result as! [NSManagedObject] {
                  inventoryItemName = object.value(forKey: "inventoryItemName") as! String
                  inventoryItemStock = object.value(forKey: "inventoryItemStock") as! Double
                  inventoryItemPG = object.value(forKey: "inventoryItemPGPercent") as! Double
                  inventoryItemVG = object.value(forKey: "inventoryItemVGPercent") as! Double
              }
          } else {

          }

          myVC.itemName.text = inventoryItemName
          myVC.itemStock.text = "\(inventoryItemStock)"
          myVC.itemPG.text = "\(inventoryItemPG)"
          myVC.itemVG.text = "\(inventoryItemVG)"

          performSegue(withIdentifier: "editInventoryItem", sender: "")
      }

更新:在进行一些打印之后,现在可以理解错误返回的原因。 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let itemName = flavors[indexPath.row] let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Inventory") request.predicate = NSPredicate(format: "inventoryItemName ==%@", itemName) if let result = try? context.fetch(request) { for object in result as! [NSManagedObject] { inventoryItemName = object.value(forKey: "inventoryItemName") as! String inventoryItemStock = object.value(forKey: "inventoryItemStock") as! Double inventoryItemPG = object.value(forKey: "inventoryItemPGPercent") as! Double inventoryItemVG = object.value(forKey: "inventoryItemVGPercent") as! Double } } else { } performSegue(withIdentifier: "editInventoryItem", sender: "") } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "editInventoryItem" { let myVC = segue.destination as! AddInventoryItemVC myVC.itemName.text = inventoryItemName myVC.itemStock.text = "\(inventoryItemStock)" myVC.itemPG.text = "\(inventoryItemPG)" myVC.itemVG.text = "\(inventoryItemVG)" } } 之前正在调用prepareForSegue(),因此该值目前为零,但我不知道如何在调用didSelectRow之前调用didSelectRow

编辑:在做了一些研究和实施Singleton之后,我已经解决了这个问题。我在Singleton中添加了一个prepareForSegue()变量,在调用didSelectRow时将变量更改为identifier。在第二个VC上,我设置了一个简单的if语句,用于将editInventoryItemidentifier进行比较并填充相关的文本字段。

谢谢大家的帮助。一个错误下来,大概要500万! :d

4 个答案:

答案 0 :(得分:1)

您的问题与核心数据无关,但您使用的是segues。方法performSegue是从故事板创建一个新的viewController。从myVC创建的instantiateViewController将在函数末尾被丢弃。而是使用prepareForSegue:sender:将值添加到viewController。

答案 1 :(得分:0)

调用performSegue:

后将调用

prepareForSegue()方法

performSegue(withIdentifier: "editInventoryItem", sender: nil)

您可以在此处将数据从SourceViewController发送到目标视图控制器。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {


    if(segue.identifier == "editInventoryItem") {
        let myVC = segue.destinationViewController as! NextViewController
        myVC.itemName.text = inventoryItemName
      myVC.itemStock.text = "\(inventoryItemStock)"
      myVC.itemPG.text = "\(inventoryItemPG)"
      myVC.itemVG.text = "\(inventoryItemVG)"
    }
}

答案 2 :(得分:0)

也许您可以尝试使用Singleton shared instance

创建一个NSObject类型的新Swift文件

YourAppState.swift

    class YourAppState : NSObject {
        class var sharedInstance: YourAppState {
          struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: YourAppState? = nil
          }

          dispatch_once(&Static.onceToken) {
            Static.instance = YourAppState()
          }

         return Static.instance!

        }
    }

有了这个,您可以执行以下操作:

在共享实例文件

中创建一个新变量

var inventoryItemName = ""

在进入下一个VC或执行segue之前, 将值赋给inventoryItemName = object.value(forKey: "inventoryItemName") as! String。在目标VC类中传递像这样的值。

self.itemName.text = YourAppState.sharedInstance().inventoryItemName

只需确保在执行segue之前添加值。

希望它有所帮助,欢呼!

答案 3 :(得分:0)

在第一个ViewController上,我的代码如下:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let itemName = flavors[indexPath.row]

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Inventory")

    request.predicate = NSPredicate(format: "inventoryItemName ==%@", itemName)
    if let result = try? context.fetch(request) {
        for object in result as! [NSManagedObject] {
            Singleton.sharedInstance.itemName = object.value(forKey: "inventoryItemName") as! String
            Singleton.sharedInstance.itemStock = object.value(forKey: "inventoryItemStock") as! Double
            Singleton.sharedInstance.itemPG = object.value(forKey: "inventoryItemPGPercent") as! Double
            Singleton.sharedInstance.itemVG = object.value(forKey: "inventoryItemVGPercent") as! Double
        }
    } else {

    }
    Singleton.sharedInstance.identifier = "editInventoryItem"
}

我的单身人士:

struct Singleton {
    static var sharedInstance = Singleton()

    var identifier = ""
    var itemName = ""
    var itemStock = 0.0
    var itemVG = 0.0
    var itemPG = 0.0
}

在第一个ViewController上,我的实现代码如下:

override func viewDidAppear(_ animated: Bool) {
    print(Singleton.sharedInstance.identifier)
    print(Singleton.sharedInstance.itemName)

    if Singleton.sharedInstance.identifier == "editInventoryItem" {
        nicotineSwitch.isEnabled = false
        VGSwitch.isEnabled = false
        PGSwitch.isEnabled = false

        itemName.text = Singleton.sharedInstance.itemName
        itemStock.text = "\(Singleton.sharedInstance.itemStock)"
        itemPG.text = "\(Singleton.sharedInstance.itemPG)"
        itemVG.text = "\(Singleton.sharedInstance.itemVG)"
        Singleton.sharedInstance.identifier = ""
    }
}