Hello there!
When using KeyPath
, it seems like the object remains in memory.
Do you think it's a bug? Or is it because for performance reasons, it is kept in memory like a static variable after the first use?
Please let me know if i'm missing something.
Here's an example code:
class Foo {
let name = "Hello World"
}
var foo: Any = Foo()
Observer.onDeinit(for: foo as! Foo) {
print("🔥 deinit foo")
}
foo = 0
var keyPath: Any = \Foo.name
Observer.onDeinit(for: keyPath as! KeyPath<Foo, String>) {
print("🔥 deinit keyPath")
}
keyPath = 0
// Prints 🔥 deinit foo
Observer
is implemented as below.
protocol ObjectType: AnyObject { }
@objc class DeinitHandler: NSObject {
var blocks: [() -> Void] = []
deinit {
blocks.forEach({ $0() })
}
}
enum Observer {
static var deinitKey = "DEINIT_KEY"
static func onDeinit(
for object: ObjectType,
block: @escaping () -> Void
) {
let handler = deinitHandler(for: object)
handler.blocks.append(block)
}
private static func deinitHandler(for object: ObjectType) -> DeinitHandler {
if let handler = objc_getAssociatedObject(object, &deinitKey) as? DeinitHandler {
return handler
} else {
let handler = DeinitHandler()
objc_setAssociatedObject(object, &deinitKey, handler, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return handler
}
}
}
extension KeyPath: ObjectType { }
extension Foo: ObjectType { }