【问题标题】:tableview reloadData crashes unexpected found nil while unwrapping optional valuetableview reloadData 在展开可选值时意外发现 nil 崩溃
【发布时间】:2017-12-19 08:37:41
【问题描述】:

我很难理解为什么 reloadData() 行会崩溃并出现以下错误“在展开可选值时意外发现 nil”(另外,为什么它是可选的?)。基本上,当用户点击一个按钮时,它会触发一个 API 请求,显示第二个 VC(recipesVC),当从 API 检索数据时,在 receivedRecipes 方法(以前的 VC)中我想从 recipesVC(currentVC)重新加载数据 由于我的数据已正确传递给 recipesVC,我不明白为什么 reloadData() 不能在同一个 VC 上工作。你能给我一点帮助吗? 谢谢。

    override func viewDidLoad() {
    super.viewDidLoad()

    let recipes = Notification.Name(rawValue: "gotRecipes")
    NotificationCenter.default.addObserver(self, selector: #selector(receivedRecipes),name: recipes, object: nil)
}

@objc func receivedRecipes() {
    let recipesVC = storyboard?.instantiateViewController(withIdentifier: "recipesList") as! RecipesViewController
    recipesVC.recipesList = request.recipeDetails
    recipesVC.recipes.reloadData()
}

【问题讨论】:

  • recipesVC.recipes 为零吗?在 VC 方面正确设置/连接?你没有出席recipesVC?在RecipesViewController 中如何声明recipes?但如果设置正确,你仍然会得到这个:stackoverflow.com/questions/12523198/…
  • recipesVC.recipes 确实为零。 recipes 正确设置为 IBOutlet 并已连接,我使用 segue 来展示 VC。当用户点击按钮时,执行 segue,显示 VC,然后当我获取数据时,我想重新加载 tableview。
  • 那肯定是因为这个:stackoverflow.com/questions/12523198/…原因是一样的。
  • 什么?你是说你已经显示了RecipesViewController(带有segue),而在之前的ViewController上,当它获取数据时,它需要对显示的RecipesViewController说重新加载?如果这就是你的意思,那显然不是你的代码在做什么:recipesVC 是一个全新的对象,而不是呈现的那个。
  • 这正是我想要做的。

标签: ios swift uitableview crash reloaddata


【解决方案1】:
 @objc func receivedRecipes() {
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "recipes"), object: nil, userInfo: ["data":request.recipeDetails])

 } 

在你当前的VC中

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(receivedRecipes(notification:)),name: NSNotification.Name(rawValue: "recipes"), object: nil)
}

 @objc func receivedRecipes(notification: Notification) {
    recipesList = notification.userInfo
    recipes.reloadData()
 }

【讨论】:

  • 这可能是最好的解决方案,但是参数 userInfo 必须是字典,而我的 request.recipedetails 变量是结构数组。
  • 我将 userInfo 作为字典传递
  • 我已经尝试了您的解决方案,它实际上运行良好。我已经从我的班级发布了一个通知,在那里我检索了数据,直接在 currentVC 中添加了观察者,并使用 userInfo 传递了它。无需返回点击按钮的 VC。我想通知/观察者现在对我来说更清楚了。感谢您的帮助!
【解决方案2】:

为您的数据添加验证:

func receivedRecipes() {
    guard let details = request.recipeDetails else { return }
    let recipesVC = storyboard?.instantiateViewController(withIdentifier: "recipesList") as! RecipesViewController
    recipesVC.recipesList = details
    recipesVC.recipes.reloadData()
}

下一个提示,您可以更新通知并从notification.object 获取食谱,但之前您应该将它们粘贴到:

let parsedRecipes = Recipes()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "gotRecipes"), object: parsedRecipes, userInfo: nil) 

在初始化后还显示recipesVCself.present(...)self.navigationController?.show(...)

【讨论】:

  • 为了更准确地解决我的问题,正如 Larme 所解释的,我正在展示 RecipesViewController(带有 segue),而在之前的 ViewController 上,当它获取数据时,它需要对 RecipesViewController 说显示重新加载。
  • 因此,您应该从segue 中保存ViewController 并使用它,而不是创建新的let recipesVC = storyboard?...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多