Last active
November 16, 2018 06:11
-
-
Save ilyapuchka/8d0690101f23c6d09225 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class A { | |
let factory: ()->() | |
var closure: ((b: B)->())? | |
init(factory: ()->()) { | |
self.factory = factory | |
} | |
deinit { | |
print("deinit A") | |
} | |
} | |
class B { | |
var array = [A]() | |
func addA(factory: ()->()) -> A { | |
let a = A(factory: factory) | |
self.array.append(a) | |
return a | |
} | |
func call() { | |
for a in array { | |
a.factory() | |
a.closure?(b: self) | |
} | |
} | |
deinit { | |
print("deinit B") | |
} | |
} | |
var b: B! = B() | |
b.addA({ | |
print("factory \(b)") | |
}).closure = { b in | |
print("closure \(b)") | |
} | |
b.addA({ | |
print("factory \(b)") | |
}).closure = { b in | |
print("closure \(b)") | |
} | |
b.call() | |
print("should deinit") | |
b = nil | |
b | |
/* | |
Output: | |
factory B | |
closure B | |
factory B | |
closure B | |
should deinit | |
deinit B | |
deinit A | |
deinit A | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @ilyapuchka, @AliSoftware
Got here from the playground of Dip
Sorry to resurrect this old topic, but @kballard is absolutely right. I have just confirmed that it all breaks (leaks) if the declaration is changed from an optional to a simple variable (or if the
b = nil
statement is removed)So, there are two components to this behaviour:
self
or any other variable pointing to the same object; it only is a question of indirection which is present if it's an optional)Which brings us back to the
Dip
s statement that it's safe to capture the container inside a factory - this statement doesn't seem to be valid, and this gist is actually proving that the retain cycle does exist, and has to be addressed somehow by the code.