释放自我时,无主自我不会导致运行时中断吗?
Unowned self does not cause runtime to break when self is deallocated?
我相当熟悉 swift 中的内存管理,并且我知道如果在捕获闭包中我们使用 [unowned self] 代码将会中断,如果 self 变为 nil 并且我们在 self 上调用一些方法。我仍然一直在尝试结合并发现了 curios case,self 变成了 nil,但代码永远不会中断。我试图对其进行更多测试,以解释正在发生的事情,但不能。这是示例:
class DetailsViewController: UIViewController {
var subject: PassthroughSubject<Int, Never>!
var localIntHolder: Int!
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
subject
.flatMap { [unowned self] value in
self.completionPublisher()
}
.map({ [unowned self] value in
self.increaseValue(value)
})
.sink { [unowned self] value in
print("\(value)")
self.localIntHolder = value
}
.store(in: &subscriptions)
subject.send(22)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.dismiss(animated: true, completion: nil)
}
}
private func increaseValue(_ value: Int) -> Int {
return value + 1
}
deinit {
print("deinit")
}
private func completionPublisher() -> AnyPublisher<Int, Never> {
return Future<Int, Never> { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
promise(.success(10))
}
}
.eraseToAnyPublisher()
}
}
这是主视图控制器的设置:
let subjectInt = PassthroughSubject<Int, Never>()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let controller = DetailsViewController()
controller.subject = subjectInt
present(controller, animated: true, completion: nil)
}
现在这是一个简单的例子,发送方将发送值,未来将延迟 10 秒。在发生这种情况时,我在其中释放了控制器。我想代码会中断,但什么也没有发生,控制器被释放,管道的其余部分从未执行。
有没有我缺少的组合魔法?
存储subscriptions
在
.store(in: &subscriptions)
确保订阅不会立即解除分配,因为控制器通过其 subscriptions
变量拥有它们(强烈引用它们)。
当控制器被释放时,subscriptions
也是deallocated
。在取消分配期间订阅也被取消,因此整个链被取消(例如包括异步请求)。这意味着订阅将不再 运行 并且他们无法访问 [unowned self]
.
我相当熟悉 swift 中的内存管理,并且我知道如果在捕获闭包中我们使用 [unowned self] 代码将会中断,如果 self 变为 nil 并且我们在 self 上调用一些方法。我仍然一直在尝试结合并发现了 curios case,self 变成了 nil,但代码永远不会中断。我试图对其进行更多测试,以解释正在发生的事情,但不能。这是示例:
class DetailsViewController: UIViewController {
var subject: PassthroughSubject<Int, Never>!
var localIntHolder: Int!
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
subject
.flatMap { [unowned self] value in
self.completionPublisher()
}
.map({ [unowned self] value in
self.increaseValue(value)
})
.sink { [unowned self] value in
print("\(value)")
self.localIntHolder = value
}
.store(in: &subscriptions)
subject.send(22)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.dismiss(animated: true, completion: nil)
}
}
private func increaseValue(_ value: Int) -> Int {
return value + 1
}
deinit {
print("deinit")
}
private func completionPublisher() -> AnyPublisher<Int, Never> {
return Future<Int, Never> { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
promise(.success(10))
}
}
.eraseToAnyPublisher()
}
}
这是主视图控制器的设置:
let subjectInt = PassthroughSubject<Int, Never>()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let controller = DetailsViewController()
controller.subject = subjectInt
present(controller, animated: true, completion: nil)
}
现在这是一个简单的例子,发送方将发送值,未来将延迟 10 秒。在发生这种情况时,我在其中释放了控制器。我想代码会中断,但什么也没有发生,控制器被释放,管道的其余部分从未执行。
有没有我缺少的组合魔法?
存储subscriptions
在
.store(in: &subscriptions)
确保订阅不会立即解除分配,因为控制器通过其 subscriptions
变量拥有它们(强烈引用它们)。
当控制器被释放时,subscriptions
也是deallocated
。在取消分配期间订阅也被取消,因此整个链被取消(例如包括异步请求)。这意味着订阅将不再 运行 并且他们无法访问 [unowned self]
.