Miguel Schulz
03/17/2023, 10:48 AMweak
to avoid reference cycles. Without having Class2.class1 as weak in the following example, this would be a reference cycle and setting Entry.class1 to nil would not release Class1 because it is still hold in a strong reference by Class2, which is hold by Class1 and so on.
class Entry {
private var class1: Class1?
func start() {
class1 = Class1()
class1!.start()
}
func end() {
class1 = nil
}
}
class Class1 {
lazy var class2 = Class2(class1: self)
func start() {
print(class2)
}
}
class Class2 {
weak var class1: Class1?
}
Now lets define Class2 not in Swift, but in Kotlin, and it holds a reference to Class1 that implements Class1Protocol.
Kotlin:
protocol Class1Protocol {
fun start()
}
class Class2(var class1: Class1Protocol)
Swift:
class Class1: Class1Protocol {
lazy var class2 = Class2(class1: self)
func start() {
print(class2)
}
}
This leads to the reference cycle described above. How can we make sure that Class1 and Class2 get released properly when Entry.end() is called?
We know about using expect/actual WeakReference, but this does not seem optimal. Are there any other approaches you can recommend?
CC @Paul Woitaschek @Sebastian MuggelbergCLOVIS
03/17/2023, 11:00 AMPaul Woitaschek
03/17/2023, 11:35 AMclass NoKotlin {
init(){
print("I'm NoKotlin")
}
deinit{
print("Bye NoKotlin")
}
}
class YesKotlin {
var ref : KotlinRef? = nil
init(){
self.ref = KotlinRef(instance: self)
print("I'm YesKotlin. I never say bye!")
}
deinit{
print("Bye YesKotlin")
}
}
func run() {
NoKotlin()
YesKotlin()
}
I think this demonstrates it quite well with the kotlin part being:
public class KotlinRef(public val instance: Any)
I'm NoKotlin
Bye NoKotlin
I'm YesKotlin. I never say bye!
CLOVIS
03/17/2023, 12:20 PMMiguel Schulz
03/17/2023, 12:21 PMJeff Lockhart
03/17/2023, 1:24 PMMiguel Schulz
03/17/2023, 1:30 PMJeff Lockhart
03/17/2023, 1:41 PMkotlin.native.internal.GC.collect()
after releasing the Kotlin reference?