为什么协议类型永远不会得到值?

问题描述

我正在尝试了解更多协议。我无法弄清楚 myProtocolFunction 永远不会调用和打印或传递如下变量。

我认为我的问题是关于初始化。当我尝试使用两个视图控制器时,一切正常,但 MyStruct 协议实例为零。感谢您的帮助。

class ViewController: UIViewController,MyProtocol {
    var myProtocolValue: String = ""
    
    var globalInstance = "a"

    override func viewDidLoad() {
        super.viewDidLoad()
                
    }
    
    
    @IBAction func click(_ sender: Any) {
        
        var myStruct = MyStruct()
        myStruct.myProtocol = self        
    }
    

    func myProtocolFunction(passing: String) {
        globalInstance = passing
        print("never print")
    }
}

protocol MyProtocol {
    func myProtocolFunction(passing: String)
}


struct MyStruct {

    var myProtocol: MyProtocol?
    
    init() {
        makeSomething()
    }
    
    func makeSomething() {
        myProtocol?.myProtocolFunction(passing: "abc")
        
    }
}

解决方法

1- 你需要制作

var myStruct = MyStruct() // an instance variable 

@IBAction func click(_ sender: Any) {
    
    myStruct.myProtocol = self        
}

2- 你甚至在你设置 init 之前调用了 myProtocol,当你执行 var myStruct = MyStruct() 并且那时 myProtocol 为零,因为它尚未设置

init() {
    makeSomething()
}

检查完整的工作编辑

class ViewController: UIViewController,MyProtocol {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
    }
    
    func myProtocolFunction(passing: String) {
        print(passing)
    }
     
    @IBAction func click(_ sender: Any) {
          
        var myStruct = MyStruct(self)
        
    }
     
}

protocol MyProtocol {
    func myProtocolFunction(passing: String)
}

struct MyStruct {

    var myProtocol: MyProtocol?
    
    init(_ mine:MyProtocol) {
        myProtocol = mine
        makeSomething()
    }
    
    func makeSomething() {
        myProtocol?.myProtocolFunction(passing: "abc")
        
    }
}
,

protocols 视为一种类型,在您的结构中,您基本上是在说 这个结构有一个这种类型的变量(你的协议) 并在 init 上尝试调用其函数。

您缺少的是设置类型的实例(您的协议) 所以它可以被调用。

例如:

MyStruct = MyStruct(myProtocol: ViewController())

现在你的可为空的协议有一个值并且可以用换句话说来调用它的函数,协议不能直接在它们中实现它们更像是一个签名合同

阅读有关协议 here 的更多信息。

,

您需要在单击操作之外创建 MyStruct() 对象,否则当范围超过您的对象被取消初始化时。

此外,您必须在按钮单击时调用 .makeSomething() 函数,因为对象创建委托的时间为零。

var myStruct = MyStruct() // Create an instance here

@IBAction func click(_ sender: Any) {
    myStruct.myProtocol = self        
// Add your action
    myStruct.makeSomething()
}