使用 typealias 从回调转移到委托
Posted
技术标签:
【中文标题】使用 typealias 从回调转移到委托【英文标题】:Moving from callback to delegation with typealias 【发布时间】:2021-06-02 16:03:15 【问题描述】:我是 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) -> Void” 调用中的额外参数原来的可选回调定义和调用被注释掉了。我首先尝试在没有协议的情况下将makeNewNote
重写为类型别名,但仍然遇到相同的错误。
我还尝试从MakeNewNote
中删除?
,但这产生了一个新错误:
我尝试了很多谷歌搜索,已经好几个小时了。谁能帮我找出问题所在或指出正确的方向?提前致谢。
【问题讨论】:
您似乎没有阅读任何有关如何编写委托的指南。您需要在协议中编写方法,而不是类型别名。请参阅 MakeAppPie 的答案。 【参考方案1】:你很困惑。在协议中定义类型别名没有任何价值。您不妨将 typealias 设为全局。它只是定义了一个类型。您希望您的协议定义符合对象支持的方法和属性:
protocol NewNoteDelegate: class
func makeNewNote(_: String, _: String)
这只是意味着任何符合 NewNoteDelegate 协议的对象都必须实现 makeNewNote(:,:) 函数。
我不确定函数 return Void?
的作用,所以我把它去掉了。
另请注意,在 Swift 中,具有两个匿名参数的函数被认为是错误的形式。您应该真正命名所有参数(可能第一个参数除外)。在 Swift 中,名称让您知道每个参数的用途。
考虑一下这个示例代码(编译为 Mac 命令行工具,但它也可以很容易地成为 Playground。我只是碰巧不喜欢 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'
【讨论】:
以上是关于使用 typealias 从回调转移到委托的主要内容,如果未能解决你的问题,请参考以下文章
Swift typealias associatedType
尝试从 UIView 的按钮转移到另一个 ViewController 时,委托不起作用
注册 C# 委托给 C++ 回调,Marshal.GetFunctionPointerForDelegate 有啥作用?
asihttp 使用 POST 方法并将 nsMutabledata 发布到 uri,为啥我无法获得 asi 委托回调?