在Swift中委派错误

时间:2014-11-23 14:51:04

标签: ios swift

我正在尝试使用代理从double(从XIB加载)向UIView发送ViewController

这是我的协议,它只是在点击按钮时向主ViewController发送一个双。

protocol HoursWorkedDelegate{
    func sendHoursWorked(hoursWorked: Double);
}

class HoursWorkedView: UIView{

    var delegate: HoursWorkedDelegate?;

    @IBAction func calculateHoursWorked(sender: AnyObject){

        // Do some calculations for the hoursWorked value


        // Give value 
        delegate!.sendHoursWorked(hoursWorked);
    }

}



// This class now wants that Double value
class ViewController: UIViewController, HoursWorkedDelegate{


    // Conform to protocol
    func sendHoursWorked(hoursWorked: Double){

        // Lets say we just want to assign this value to a textField
        hoursWorkedTextField.text = NSString(format: "%.4f", hoursWorked);
    }

}

我收到的错误消息是Thread 1: EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP, subcode=0x0)

非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

首先,将此代码段中的感叹号更改为问号:

delegate!.sendHoursWorked(hoursWorked);

这可能会导致崩溃,因为您强制解包可选的委托属性。问号意味着如果委托存在,我们只会在委托上调用sendHoursWorked()

现在,修复程序可能意味着您的程序不再崩溃,但仍然无法获得所需的结果,因为永远不会调用sendHoursWorked()。我们必须告诉我们的HoursWorkedView对象谁委托它。

在代码的某处,您可能会遇到以下情况:

let hoursWorkedView = HoursWorkedView()

self.view.addSubview(hoursWorkedView)

这就是我们应该设置代表的地方:

let hoursWorkedView = HoursWorkedView()
hoursWorkedView.delegate = self
self.view.addSubview(hoursWorkedView)

虽然如果是我,我可能会向HoursWorkedView添加一个接受委托属性的构造函数:

init(delegate: HoursWorkedDelegate) {
    super.init()
    self.delegate = delegate
}

现在我们可以这样做:

let hoursWorkedView = HoursWorkedView(delegate: self)
self.view.addSubview(hoursWorkedView)

答案 1 :(得分:0)

我认为您正在查看视图并且您的viewcontroller混乱:ViewController控制着事物;视图只显示它们。 viewController告诉视图要显示的内容。

因此,您希望将按钮连接到viewController而不是视图。而且您不需要自定义视图类或委托。

像这样设置:

  • 创建一个textField和一个按钮
  • 为textField
  • 创建一个插座
  • 将calculateHoursWorked直接放在viewController
  • 创建一个操作以将按钮连接到calculateHoursWorked
  • 在calculateHoursWorked中,将self.textField.text设置为计算结果(其中" textField"是您命名为插座的任何内容)

您不会在此上下文中使用委托,因为viewController知道视图所做的一切。委托模式适用于一个对象无法看到另一个对象的情况。

编辑:

话虽如此,这里的错误是代表实际上并未在任何地方设置。

Swift Optionals(!和?)有助于防止这种情况发生。如果使用!显式展开可选项,则必须确保始终定义它。在这种情况下,由于委托被定义为可选(?),您必须检查它:

@IBAction func calculateHoursWorked(sender: AnyObject){

    // Do some calculations for the hoursWorked value


    // Give value 
    if let currentDelegate = self.delegate {
        currentDelegate.sendHoursWorked(hoursWorked)
    }
}