我无法弄清楚如何为类/结构中定义的计算变量获取正确的内存地址。我以以下方式定义了一个类(结构也类似):
class TestClass {
private var a = "Hello"
var getterSetter: String {
get {
return a
}
set {
a = newValue
}
}
}
为了简单起见,假设我将 ViewController 定义如下:
class ViewController: UIViewController {
private let testClass = TestClass()
override func viewDidLoad() {
super.viewDidLoad()
demoMethod()
print("--------")
print(testClass.getterSetter) //Prints "I'm here"
/// Address of testClass
print("Address of testClass: \(Unmanaged.passUnretained(self.testClass).toOpaque())")
/// Address of computed variable in testClass
withUnsafePointer(to: &self.testClass.getterSetter) {
print("Address of computed variable: \(String(format: "%p", $0.pointee))")
}
print("--------")
}
private func demoMethod() {
Observable.just(())
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
self.testClass.getterSetter = "I'm here"
print("*****")
/// Address of testClass
print("Address of testClass: \(Unmanaged.passUnretained(self.testClass).toOpaque())")
/// Address of computed variable in testClass
withUnsafePointer(to: &self.testClass.getterSetter) {
print("Address of computed variable: \(String(format: "%p", $0.pointee))")
}
print("*****")
})
.disposed(by: DisposeBag())
}
}
getterSetter变量的值在demoMethod函数中被访问和设置,使用一个简单的Observable,这反过来将a更改为"I'm here"。我在 demoMethod 函数内以及在此函数返回之后打印 testClass 和 getterSetter 变量的地址。
请查看此处显示输出的链接。
正如我们从图像中看到的那样,testClass 实例地址保持不变,正如预期的那样。但是,getterSetter 变量的地址在每次打印时显示不同,这没有意义,因为私有变量 a更改为“我在这里”(可以在输出链接中看到),这意味着它们应该指向相同的记忆。
如果我从 demoMethod 中删除self.testClass.getterSetter = "I'm here",它将开始提供正确且相同的内存地址,如下所示:
- 我相信它必须与Copy on Write机制有关,但我无法弄清楚到底是什么。如果在我执行self.testClass.getterSetter = "I'm here"时将原始实例复制到新内存,那么原始内存地址的值怎么会改变?
- 那么,这里到底发生了什么,内存是如何分配的?
PS此外,当我使用struct TestClass代替类 TestClass时,观察到完全相同的事情,唯一的区别是,我使用print("Address of testClass: (String(format: "%p", unsafeBitCast(self.testClass,到:String.self)))“)