Hi! Recently I discovered a way to make a bad access crash in somewhat
unexpected circumstances. Code to reproduce:
import Foundation
class Storage<T> {
var val : T?
}
class A {
let s : Storage<A>
init(s : Storage<A>) {
self.s = s
}
deinit {
s.val = self;
}
}
var storage : Storage<A> = Storage()
var a : A? = A(s: storage)
a = nil
DispatchQueue.main.async {
print(storage.val as Any)
}
dispatchMain()
We saving self in storage on deinit. Storage will retain `a`, but after it `a`
will be destroyed. So, `val` will point to object that was deallocated. When we
will try to access it, it will crash.
Can we do something about it? Of course, this very evil thing to do, but,
unfortunately, swift allows to do that. I have two suggestions:
1. Completely forbid accessing self in deinit, allowing readonly access only to
properties with default getter method. This is very strict, but will catch such
problems in compile time.
2. The bigger problem here, not just that it will crash, but it will crash in
very unpredictable place. So, we can make it crash just after deinit method, if
retain count was changed after deinit.
I'm new to swift evolution, so please forgive me if I'm doing something wrong
:) Thanks!_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution