在Swift中使用值类型进行委派?

时间:2017-03-29 16:38:43

标签: ios swift delegates

在我的应用程序中,我使用委派:Controller C使用委托D1和名为M1的模型项,M1使用委托与另一个名为{{1的模型项}}

M2M1调用委托方法时,一切都很好。

C

C ---> M1 <----- delegation : OK M2调用委托方法时,一切都很好。

M1

但是当M1 ---> M2 <------ delegation : OK M2调用委托方法时,它会从M1调用委托方法,但这不起作用。

C

调试程序显示C ---> M1 ---> M2 <------ delegation <------ delegation 中委托的值为nil,因为它应为M1

更新

C

预期结果:

protocol TestOneDelegate:class {

    func testMethodOne(message:String)

}

protocol TestTwoDelegate {

    func testMethodTwo(message:String)

}

//
struct M2 {

    var delegate:TestTwoDelegate?

    func testOperation() {
        delegate?.testMethodTwo(message:"From M2" )
    }
}


struct M1:TestTwoDelegate {

    weak var delegate:TestOneDelegate?
    var m2:M2

    init() {
        m2 = M2()
        m2.delegate = self
    }

    mutating func testOperation() {
        delegate?.testMethodOne(message: "From M1 - Start")

        // BREAKPOINT 1
        m2.testOperation()

        delegate?.testMethodOne(message: "From M1 - End")

    }

    /// Implementation of TestTwoDelegate
    func testMethodTwo(message:String) {

        // BREAKPOINT 2
        print ("M1 get message from M2: " + message)
        delegate?.testMethodOne(message: message + " via M1")
    }

}


class TestControler:UIViewController,TestOneDelegate {

    var m1:M1!

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)

        m1 = M1()
        m1.delegate = self
        m1.testOperation()
    }

    /// Implementation of TestOneDelegate
    func testMethodOne(message:String) {
        print ("Controller get following message from M1: " + message)
    }


}

获得的结果:

Controller get following message from M1: From M1 - Start
M1 get message from M2: From M2
Controller get following message from M1: From M2 via M1  
Controller get following message from M1: From M1 - End

Controller get following message from M1: From M1 - Start M1 get message from M2: From M2 Controller get following message from M1: From M1 - End 缺少...

停在'BREAKPOINT 1'上,From M2 via M1有一个值 停在'BREAKPOINT 2'上,delegate为零。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

答案由@OOper

提供

使用值类型赋值创建实例的副本。因此,在class PersonalDetailSerializer(serializers.ModelSerializer): ... icon = serializers.FileField(source='details_sample.icon', read_only=True) ... class Meta: model = PersonalDetail fields = ( ..., 'icon', ... ) 中,M1.init()创建实例的副本,然后将其分配给m2.delegate = self。因此,对M1实例所做的任何修改都不会反映到m2.delegatem2.delegate m2.delegate

部分与 Swift编程语言的类和结构相关引用:

  

作为一般准则,考虑在满足以下一个或多个条件时创建结构:
  ...
   - 结构存储的任何属性本身都是值类型,也可以复制而不是引用它们。

这个问题的最佳答案是在需要委派​​时使用nil代替class

出于好奇心的目的,以下是对仍然使用struct的初始问题的两个答案。请注意,这些解决方案仅适用于此示例的范围。如果struct的控制器访问属性可能会出现问题。

我们说m1现在修改testMethodTwo属性:

m1

然后当方法func testMethodTwo(message:String) { // Properties are modify here // BREAKPOINT 2 print ("M1 get message from M2: " + message) delegate?.testMethodOne(message: message + " via M1") } 被调用时,控制器将不会在testMethodOne上看到这些修改,因为它们出现在m1的不同副本上。

1。使用委托

初始化
m1

2。传播更新

struct M1:TestTwoDelegate {

    var m2 = M2()
    weak var delegate:TestOneDelegate?


    init(delegate:TestOneDelegate) {
        self.delegate = delegate
        m2.delegate = self
    }