我正在尝试使用代理从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)
非常感谢任何帮助,谢谢!
答案 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而不是视图。而且您不需要自定义视图类或委托。
像这样设置:
您不会在此上下文中使用委托,因为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)
}
}