spxbhuhb / adaptive

Consolidated full-stack application development library for Kotlin
Apache License 2.0
0 stars 0 forks source link

Solve iOS gradient color issue #31

Closed toth-istvan-zoltan closed 18 hours ago

toth-istvan-zoltan commented 4 days ago

Setting the colors for gradient is problematic because of memory management issues.

This code seems like working, but it leaks memory:

gradientLayerc.colors = 
    listOf(
        CFBridgingRelease(CFRetain(UIColor.redColor.CGColor)), 
        CFBridgingRelease(CFRetain(UIColor.yellowColor.CGColor))
    )

This code (from the YouTrack issue) crashes:

gradientLayer.colors = NSArray.arrayWithObjects(
    UIColor.redColor.CGColor, UIColor.yellowColor.CGColor
)

I'm not 100% sure that the problem is the colors or the CAGradientLayer. From the memory graph dump it seems like the gradient layer is not released.

Additional information:

Screenshot 2024-06-30 at 14 01 30 Screenshot 2024-06-30 at 14 02 17
toth-istvan-zoltan commented 4 days ago

Without adding the gradient, everything is fine, there is no apparent memory leak.

Testing with Good Morning

Ran for 3 hours without gradient, memory usage was between 47 MB and 52 MB after three hours.

Also did a few few minutes and compared memory graph instance numbers, no noticeable change in any categories.

toth-istvan-zoltan commented 4 days ago

After spending a lot of time on this, it seems like this is a rather hard issue to solve. There are quite a few posts about CALayer leaking memory.

https://youtrack.jetbrains.com/issue/KT-54805

I tries calling GC right after the I set the sublayers to null. Nope, still leaks.

fragment.receiver.layer.sublayers = null
kotlin.native.runtime.GC.collect()
toth-istvan-zoltan commented 4 days ago
fragment.receiver.layer.sublayers?.forEach {
     it as CALayer
     it.removeFromSuperlayer()
}
kotlin.native.runtime.GC.collect()

Nope.

toth-istvan-zoltan commented 4 days ago
        fragment.receiver.layer.sublayers?.forEach {
            it as CALayer
            it.removeFromSuperlayer()
            it.delegate = null
            it.removeAllAnimations()
        }
        kotlin.native.runtime.GC.collect()

Nope.

toth-istvan-zoltan commented 18 hours ago

Figured it out, was a problem in reapplication of instructions.