微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 typealias 从回调转移到委托

如何解决使用 typealias 从回调转移到委托

我是 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 但产生了一个错误

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

我尝试了很多谷歌搜索,已经过了几个小时。任何人都可以帮助我找出问题所在或指出我正确的方向吗?提前致谢。

解决方法

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

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

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

我不确定函数 return Void? 到底有什么作用,所以我把它去掉了。

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

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

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'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。