![](/img/trans.png)
[英]Swift: Change value of another ViewController with delegation programmatically
[英]Delegation with value types in Swift?
在我的应用程序中,我使用委托:控制器C
使用委托D1
和名为M1
的模型项目, M1
使用委托与另一个名为M2
模型项目。
当M1
从C
调用委托方法时,一切都很好。
C ---> M1
<----- delegation : OK
当M2
从M1
调用委托方法时,一切都很好。
M1 ---> M2
<------ delegation : OK
但是当M2
从M1
调用委托方法时,又从C
调用委托方法,这不起作用。
C ---> M1 ---> M2
<------ delegation
<------ delegation
调试器显示M1
委托的值为nil,因为它应该是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
From M2 via M1
失踪...
停在'BREAKPOINT 1'上, delegate
有一个值。
停在'BREAKPOINT 2'上, delegate
是零。
我错过了什么吗?
答案是由@OOper给出的
使用值类型赋值创建实例的副本。 所以在M1.init()
, m2.delegate = self
创建实例的副本,然后将其分配给m2.delegate
。 因此,对M1实例所做的任何修改都不会反映到m2.delegate
, m2.delegate
也是nil
。
与Swift编程语言的 类和结构相关的部分引用:
作为一般准则,考虑在以下一个或多个条件适用时创建结构:
...
- 结构存储的任何属性本身都是值类型,也可以复制而不是引用它们。
所以这个问题的最佳答案是在需要委托时使用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
,因为它们发生在一个独特的副本m1
。
struct M1:TestTwoDelegate {
var m2 = M2()
weak var delegate:TestOneDelegate?
init(delegate:TestOneDelegate) {
self.delegate = delegate
m2.delegate = self
}
struct M1:TestTwoDelegate {
var m2 = M2()
weak var delegate:TestOneDelegate? {
didSet {
m2.delegate = self
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.