exyte / Macaw

Powerful and easy-to-use vector graphics Swift library with SVG support
MIT License
6.01k stars 554 forks source link

Memory leak due to strongly retained Variable<T> #686

Open bikram990 opened 4 years ago

bikram990 commented 4 years ago

I'm loading a Node using SVGParser and creating Images. The Node is not getting released if the scope in which it was created as ended.

Expected Result: Node object should be freed as soon as its no longer retained by the App.

Actual Result: Node object is retained by Variable<T> for AnimatableVariable<Transform> creating a cyclic reference.

amarunko commented 4 years ago

Hello, @bikram990, can you provide a little bit more information? Because as in code - AnimatableVariable has a weak link on a node. Or maybe you can provide example test project with a memory link for investigation, it will help us a lot.

clding commented 4 years ago

renderer.dispose() //add call dispose()???

public extension Node {

    func toNativeImage(size: Size, layout: ContentLayout = .of()) -> MImage {
        let renderer = RenderUtils.createNodeRenderer(self, view: nil)
        let rect = size.rect()

        MGraphicsBeginImageContextWithOptions(size.toCG(), false, 1)
        let ctx = MGraphicsGetCurrentContext()!
        ctx.clear(rect.toCG())

        let transform = LayoutHelper.calcTransform(self, layout, size)
        ctx.concatenate(transform.toCG())
        renderer.render(in: ctx, force: false, opacity: self.opacity)

        let img = MGraphicsGetImageFromCurrentImageContext()
        MGraphicsEndImageContext()

        renderer.dispose()  //add call dispose()???

        return img!
    }

}
amarunko commented 4 years ago

Honestly, I don't think so, renderer dispose all disposables on deinit, exception is - animation observers, but during rendering to native image we don't work with any kinds of animations