Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I get memory leak when I execute CTFontManagerRegisterGraphicsFont

I am wondering why I am receiving memory leak in case when CTFontManagerRegisterGraphicsFont is called. Is it possible because it is debug build ? Or it is connected with wrong usage of the apple API?

public static func register(from url: URL) throws {
    guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
        throw RegisterFontError(errorMessage: "Could not create font data provider for \(url).")
    }
    
    let font = CGFont(fontDataProvider)
    var error: Unmanaged<CFError>?
    guard CTFontManagerRegisterGraphicsFont(font, &error) else {
        throw error!.takeUnretainedValue()
    }
}

Apple Instruments :

enter image description here

like image 422
Oleg Gordiichuk Avatar asked Apr 12 '17 08:04

Oleg Gordiichuk


1 Answers

After investigation of the parameters of the CTFontManagerRegisterGraphicsFont I found that error parameter is type of UnsafeMutablePointer<Unmanaged<CFError>?>?. And the main issue is connected with Unmanaged type.

So what is Unmanaged type.

An Unmanaged wrapper, like an Optional wrapper, provides a layer of safety between your code and a potentially nasty crash. The Unmanaged type stores a pointer whose memory is not controlled by the Swift runtime system. Before using this data, you take responsibility for how this memory should stay alive.

And what is UnsafeMutablePointer

UnsafeMutablePointer provides no automated memory management or alignment guarantees. You are responsible for handling the life cycle of any memory you work with through unsafe pointers to avoid leaks or undefined behavior.

So as it possible to understand we should fix my code with this few code lines.That will release error after we fetch error description.

   public static func register(from url: URL) throws {
        guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
            throw RegisterFontError(errorMessage: "Could not create font data provider for \(url).")
        }

        let font = CGFont(fontDataProvider)

        var error: Unmanaged<CFError>?
        guard CTFontManagerRegisterGraphicsFont(font, &error) else {
            let message = error.debugDescription
            error?.release()
            throw RegisterFontError.init(errorMessage: message)
        }

    }
like image 161
Oleg Gordiichuk Avatar answered Sep 23 '22 20:09

Oleg Gordiichuk