Swift 2.1 - 在委托方法调用中展开Optional时出乎意料地发现nil [英] Swift 2.1 - Unexpectedly found nil while unwrapping an Optional on delegate method call

查看:81
本文介绍了Swift 2.1 - 在委托方法调用中展开Optional时出乎意料地发现nil的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下两个ViewControllers(一个是TableViewController)
CategoryTableViewController有一个委托方法,当选择Table Cell时将调用该方法。然后CreateRecipeViewController实现此委托方法并处理选定的类别字符串。

I have the following two ViewControllers (one is TableViewController) that CategoryTableViewController has a delegate method which will be called when Table Cell is selected. Then CreateRecipeViewController implements this delegate method and handles the selected category string.

我收到致命错误:在解包可选时意外发现nil delegate.categoryController(self,didSelectCategory:categoryCell)

print(categoryCell)正确打印所选表格单元格的字符串值,所以我不确定为什么会收到此错误。

print(categoryCell) correctly prints the string value of selected table cell so I'm not sure why I'm getting this error.

我是实施协议的新手,所以我可能很有可能做错了。如果有人能给我一个这个错误的线索,我将非常感激。

I'm new to implementing protocol so there may be a high chance I'm doing this wrong. I'd much appreciate if some one can give me a clue of this error.

CategoryTableViewController(选择类别)

protocol CategoryTableViewControllerDelegate: class {
    func categoryController(controller: CategoryTableViewController, didSelectCategory category: String)
}

class CategoryTableViewController: UITableViewController {

    ...

    weak var delegate: CategoryTableViewControllerDelegate!

    ...

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {        

        if let categoryCell = recipeCategory[indexPath.row].name {
            print(categoryCell)
            delegate.categoryController(self, didSelectCategory: categoryCell)
        }
    }

}

CreateRecipeViewController(接收所选类别)

extension CreateRecipeViewController: CategoryTableViewControllerDelegate {
    func categoryController(controller: CategoryTableViewController, didSelectCategory category: String) {

        let selectedCategory = category
        dismissViewControllerAnimated(true, completion: nil)

        let cell = RecipeCategoryCell()
        cell.configureSelectedCategoryCell(selectedCategory)

        recipeCategoryTableView.reloadData()
    }
}

更新

推荐答案

问题是你忘记了为属性委托分配值。换句话说,委托为零。

The problem is that you forgot to assign a value to the property delegate. In other words, delegate is nil.

由于委托是一个隐式未扭曲的可选类型,您无需添加问号或感叹号来打开它。这就是你没有看到错误的原因。

Since delegate is an implicitly unwarped optional type, you don't need to add a question mark or an exclamation mark to unwrap it. This is why you didn't see the mistake.

要解决这个问题,只需在委托之后加上一个问号:

To solve this, just put a question mark after delegate:

delegate?.categoryController(self, didSelectCategory: categoryCell)

但这并不能解决问题!这样, categoryController(:didSelectCategory:)永远不会被调用!

But that doesn't solve the problem! This way, categoryController(:didSelectCategory:) will never be called!

不幸的是,我想不出办法使用委托在视图控制器之间传递数据。但有一种更简单的方法。

Unfortunately, I cannot think of a way to pass data between view controllers using delegation. But there is a simpler way to do that.

为简单起见,让我们调用 CategoryTableViewController sender CreateRecipeViewController 接收者。

For simplicity, let's call CategoryTableViewController the sender and CreateRecipeViewController the receiver.

这就是我想你想做的事情。您希望用户在发件人中选择一个类别,并将所选类别传递给接收者。所以在发件人中,你需要调用 performSegueWithIdentifier ,对吧?

This is what I guess you want to do. You want the user to select a category in the sender and pass the selected category to the receiver. So in the sender, you need to call performSegueWithIdentifier, right?

当视图要执行一个segue时, prepareForSegue 被调用。您需要覆盖该方法:

When the view is going to perform a segue, prepareForSegue is called. You need to override that method:

override func prepareForSegue(segue: UIStoryBoardSegue) {
    if segue.identifier == "your segue's identifier" {
        let destinationVC = segue.destinationViewController as! reciever
        destinationVC.selectedCategory = self.selectedCategory
    }
}

上面的代码中有一些未定义的东西。我们现在定义它们。

There is some stuff that is undefined in the above code. Let's define them now.

首先是 destination.selectedCategory 。您在接收器中添加了一个属性:

The first thing is destination.selectedCategory. You add a property in the receiver:

var selectedCategory: String!

在收件人的 viewDidLoad 中,你可以使用此属性来了解用户选择的内容。换句话说,数据将传递给此属性。

In the viewDidLoad of the receiver, you can use this property to know what the user selected. In other words, the data is passed to this property.

第二个是 self.selectedCategory 。我们也在发件人中定义:

The second is self.selectedCategory. Let's define that as well, in the sender:

var selectedCategory: String!

tableView(:didSelectRowAtIndexPath:indexPath :)中发件人,您需要指定 self.selectedCategory 所选类别:

In the tableView(:didSelectRowAtIndexPath:indexPath:) of sender, you need to assign self.selectedCategory the category selected:

self.categorySelected = recipeCategory[indexPath.row].name

和BOOM!就是这样!

And BOOM! That's it!

这篇关于Swift 2.1 - 在委托方法调用中展开Optional时出乎意料地发现nil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆