ios Swift ViewController 从选择 TableView 单元格中加载丢失引用

ios Swift ViewController Loaded from Selecting TableView Cell Loses Reference

此分支的完整代码 here

选择单元格时,视图控制器 "MovieDetailsVC" 会呈现给导航控制器。

呈现视图控制器,"ViewController",存储 tableView 的行以在 NSUserDefaults 中显示为 Int。

"MovieDetailsVC" 读取行正常。然后它从 CoreData 中提取整个自定义 class 信息数组,并将数组行存储在 属性 中。

一开始数据显示正常。 IBOutlet 连接设置正常。我已经断开并重新连接了 MovieDetailsVC 上的所有插座两次,所以应该没问题。

"viewDidLoad"称为连续时间。不确定来自哪里。调用的时候,coredata实体和行号都拉ok了。

问题在第 "lblTitle.text = self.movieRecord.title" 行。我假设任何 IBOutlets 都会导致同样的问题。

抛出的错误是插座未连接时您会看到的错误:

致命错误:展开可选值时意外喜欢 nil。

MovieDetailsVC 的代码如下。任何关于为什么这个插座 link 在正常工作后会坏掉的想法都将不胜感激。

import UIKit
import CoreData

class MovieDetailsVC: UIViewController {

@IBOutlet var lblTitle: UILabel!
@IBOutlet var lblDescr: UILabel!
@IBOutlet var lblLink: UILabel!
@IBOutlet var imgMovie: UIImageView!


var movieRecord:FavMovie!

var favMovies = [FavMovie]()

override func viewDidLoad() {
    super.viewDidLoad()

    fetchAndSetResult()

}

func fetchAndSetResult() {


    let app = UIApplication.sharedApplication().delegate as! AppDelegate
    let context = app.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: "FavMovie")

    do {
        let results = try context.executeFetchRequest(fetchRequest)
        self.favMovies = results as! [FavMovie]
    } catch let err as NSError {
        print(err.description)
    }

    if let row = NSUserDefaults.standardUserDefaults().objectForKey("movieRow") as? Int {

        self.movieRecord = self.favMovies[row]

        configureCellDescr()

    }


}

func configureCellDescr() {
    lblTitle.text = self.movieRecord.title
    lblDescr.text = self.movieRecord.descrWhyGood
    lblLink.text = self.movieRecord.linkImdb
    imgMovie.image = self.movieRecord.getImg()
}

}

我刚刚查看了您在 github 中的源代码并找到了问题所在。有两个问题,我会在下面解释。

it does that the second time that the app overrides viewdidload

您的代码调用 viewDidLoad 方法两次的原因是您的情节提要中有一个将 tableViewCell 连接到 movieDetailVC 的转场。单击单元格后,这将显示 movieDetailVC。

并且在 didSelectCell 方法的代码中,您创建了另一个 movieDetailVC 对象并呈现它。

所以当您单击单元格时,实际上 movieDetailVC 会显示两次。这导致了问题。

Any ideas why this outlet link would break after working ok would be greatly appreciated

IBOutlet 为 nil 的原因是您在代码中呈现 movieDetailVC 的方式。您使用 let movieDetailsVC = MovieDetailsVC() 创建 movieDetailVC 对象。这样做,IBOutlets 将无法正确连接,因为 ios 不知道情节提要信息。

创建 MovieDetailVC 对象的正确方法是从故事板实例化。请参阅 this post 了解差异。

解决方案

您的代码设计有一个非常简单的解决方案:

只需从您的 ViewController class 中删除 let movieDetailsVC = MovieDetailsVC()self.navigationController?.presentViewController(movieDetailsVC, animated: true, completion: nil)。由于您将选择数据保存在 NSUserDefault 中,因此 cell segue 将呈现 movieDetailVC,您的 movieDetailVC 也可以从 userDefault 中获取选择数据。