通过Swift访问代理的正确方法是什么?

时间:2014-06-13 21:39:18

标签: delegates swift

我试图模仿使用Swift访问对象委托的Objective-C模式。通常我会将协议放在两个UIViewControllers共享的.h中。

目的:调用委托(主持人)来解除(推送)UIViewController。
问题:无法访问代理人的问候()。

以下代码编译,但我收到运行时错误:未知的委托方法(见下文)。

主持人/呼叫(委托)对象:

import UIKit

class MainViewController: UIViewController, ProtocolNameDelegate {                     
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    // ---------------------------------------------------------------------------------------------------------------
    // Protocol Delegate

    func hello() {
        println("Hello");
    }

    // ---------------------------------------------------------------------------------------------------------------

    @IBAction func greenAction(sender : AnyObject) { 
        let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("GreenViewController") as GreenViewController
        secondViewController.delegate = self;
        self.presentViewController(secondViewController, animated: true, completion: nil)
    }

    // ---------------------------------------------------------------------------------------------------------------

    @IBAction func exitAction(sender : AnyObject) {
        exit(0)
    }

要被解雇的推送(第二个或者#39;绿色')UIViewController:

import UIKit

@class_protocol protocol ProtocolNameDelegate {
    func hello()
}

class GreenViewController: UIViewController {
    weak var delegate: ProtocolNameDelegate?

    // ---------------------------------------------------------------------------------------------------------------

    @IBAction func returnAction(sender : UIBarButtonItem) {
        println("Inside returnAction")
        delegate?.hello()
    }  
}

修订版:更正了委托访问权限:delegate?.hello()... 并重新运行该应用程序。以下是通过调试器:

(lldb) po delegate
Some
 {
  Some = {
    payload_data_0 = 0x0d110b90 -> 0x00009a78 (void *)0x00009b70: OBJC_METACLASS_$__TtC9RicSwift218MainViewController
    payload_data_1 = 0x0d110b90 -> 0x00009a78 (void *)0x00009b70: OBJC_METACLASS_$__TtC9RicSwift218MainViewController
    payload_data_2 = 0x00000000
    instance_type = 0x00000000
  }
}
(lldb) po delegate.hello()
error: <REPL>:1:1: error: 'ProtocolNameDelegate?' does not have a member named 'hello'
delegate.hello()

(lldb) po delegate?.hello()
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0xb3145b0).
The process has been returned to the state before expression evaluation.

问题:我错过了什么或做错了什么?

3 个答案:

答案 0 :(得分:1)

这里的问题是委托是一个可选的。所以要访问它你应该

delegate?.hello()

这样就可以打开可选项,如果它不是,则调用hello

ProtocolNameDelegate?是ProtocolNameDelegate的一个独特类型,特别是Optional。

答案 1 :(得分:1)

我遇到了同样的问题。我被告知这是Swift中的一个错误(目前存在于Xcode 6 beta 5中)。强协议运行良好,但尚未实施弱协议。解决方法是使用@objc protocol ProtocolNameDelegate而不是普通protocol ProtocolNameDelegate将协议声明为Objective-C协议。

答案 2 :(得分:0)

由于委托是可选的,你必须打开它,最快的方法是使用可选的链接:

delegate?.hello()

您还需要确保委托协议被标记为@objc(在这种情况下不是@class_protocol)