从回调到带类型别名的委托



我是Swift的新手,我正试图用typealias重写一个回调委托,我迷路了:(

下面是我的代码:
protocol NewNoteDelegate: class {
typealias MakeNewNote = ((String, String) -> Void)?
}
class NewNoteViewController: UIViewController {
@IBOutlet weak private var titleField: UITextField?
@IBOutlet weak private var noteField: UITextView!
weak var delegate: NewNoteDelegate?

//    public var makeNewNote: ((String, String) -> Void)?

override func viewDidLoad() {
super.viewDidLoad()
titleField?.becomeFirstResponder()

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(didTapSave))
}

@objc func didTapSave() {
if let text = titleField?.text, !text.isEmpty, !noteField.text.isEmpty {
//            makeNewNote?(text, noteField.text)
delegate?.MakeNewNote(text, noteField.text)
}
}
}

错误如下:

  • 无法将类型'String'的值转换为期望的参数类型'(String, String) ->无效的
  • 调用中的额外参数

原始的可选回调定义和调用被注释掉。我第一次尝试重写makeNewNote作为没有协议的类型别名,但仍然得到相同的错误。

我也尝试从MakeNewNote中删除?,但产生了一个新的错误:

  • Type '(String, String) ->Void'没有成员'init'

我用谷歌搜索了好几个小时。有谁能帮我找出问题所在或者给我指出正确的方向吗?提前谢谢。

你糊涂了。在协议中定义类型别名是没有价值的。不妨将typealias设为全局。它只是定义了一个类型。您希望您的协议定义符合对象支持的方法和属性:

protocol NewNoteDelegate: class {
func makeNewNote(_: String, _: String)
}

这意味着任何符合NewNoteDelegate协议的对象都必须实现makeNewNote(:,:)函数。

我不确定有一个函数返回Void?甚至做什么,所以我剥离了它。

还要注意,在Swift中,有两个匿名参数的函数被认为是不好的形式。您应该真正命名所有参数(可能第一个参数除外)。在Swift中,名字让你知道每个参数的用途。

考虑这个示例代码(作为Mac命令行工具编译,但它也可以很容易地成为Playground。我只是碰巧不喜欢操场。

import Foundation
protocol NewNoteDelegate: class {
func makeNewNote(_: String, _: String)
}
//The Foo class has a delegate that conforms to the NewNoteDelegate protocol.
class Foo {
weak var delegate: NewNoteDelegate?
func doSomething(string1: String, string2: String) {
//Invoke our delegate, if we have one.
delegate?.makeNewNote(string1, string2)
}
}

//This class just knows how to be a NewNoteDelegate
class ADelegate: NewNoteDelegate {
func makeNewNote(_  string1: String, _ string2: String){
print("string 1 = '(string1)', string 2 = '(string2)'")
return
}
}
//Create a Foo object
let aFoo = Foo()
//Create an ADelegate object
let aDelegate = ADelegate()
//Make the ADelegate the Foo object's delegate
aFoo.delegate = aDelegate
//Tell our foo object to do something.
aFoo.doSomething(string1: "string 1", string2: "string 2")

该代码输出

string 1 = 'string 1', string 2 = 'string 2'

最新更新