#swift #rx-swift
Вопрос:
Я не могу понять, как получить правильный адрес памяти для вычисляемой переменной, определенной внутри класса/структуры. Я определил класс следующим образом (аналогично и для структуры):
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: amp;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: amp;self.testClass.getterSetter) {
print("Address of computed variable: (String(format: "%p", $0.pointee))")
}
print("*****")
})
.disposed(by: DisposeBag())
}
}
Доступ к значению переменной getterSetter осуществляется и устанавливается внутри функции demoMethod с помощью простого наблюдаемого, которое, в свою очередь, изменяет a на «Я здесь». Я печатаю адреса переменной TestClass и getterSetter внутри функции demoMethod, а также после того, как эта функция вернется.
Пожалуйста, взгляните на ссылку здесь, которая показывает результат.
Как мы видим из изображения, адрес экземпляра TestClass остается тем же, что и ожидалось. Но адрес переменной getterSetter отображается по-разному при каждой печати, что не имеет смысла, поскольку закрытая переменная a изменяется на «Я здесь» (можно увидеть в выходной ссылке), подразумевая, что они должны указывать на одну и ту же память.
Если я удалю self.TestClass.getterSetter = «Я здесь» из demoMethod, он начнет выдавать правильные и одинаковые адреса памяти, как это:
- Я считаю, что это как-то связано с механизмом копирования при записи, но я не могу точно понять, что именно. Если исходный экземпляр копируется в новую память, когда я выполняю self.TestClass.getterSetter = «Я здесь», то как получилось, что значение a изменилось по исходному адресу памяти?
- Итак, что именно здесь происходит и как распределяется память?
P.S. Кроме того, то же самое наблюдается, когда я использую struct TestClass вместо класса TestClass, с той лишь разницей, что я печатаю с помощью print(«Адрес тестового класса: (Строка(формат: «%p», Небезопасная передача(self.TestClass, в: String.self)))»)
Комментарии:
1. Сможете ли вы воспроизвести его, если исключите rx-swift из уравнения?
2. @de. Да, та же проблема возникает даже без использования rx-swift.
3. Я рекомендую вам удалить его из вашего примера, чтобы люди могли вам помочь.