2017-04-12 407 views
2

我想知道为什么我在调用CTFontManagerRegisterGraphicsFont时收到内存泄漏。这是可能的,因为它是调试版本?或者它与苹果API的错误用法相关联?当我执行CTFontManagerRegisterGraphicsFont时出现内存泄漏

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() 
    } 
} 

苹果仪器:

enter image description here

回答

3

CTFontManagerRegisterGraphicsFont的参数的调查后,我发现error参数是UnsafeMutablePointer<Unmanaged<CFError>?>?类型。主要问题与Unmanaged类型有关。

那么什么是Unmanaged类型。

非托管包装,就像一个可选包装,提供了一层代码与潜在的令人讨厌的崩溃之间的安全层。 非托管类型存储一个指针,其内存不受Swift运行时系统的 控制。在使用这些数据之前,你需要承担这个内存应该保持活着的责任。

什么是UnsafeMutablePointer

UnsafeMutablePointer没有提供自动内存管理或 对准保证。您有责任通过不安全的指针处理与您一起工作的任何内存的生命周期 以避免泄漏或未定义的行为 。

因此,我们应该理解我们应该使用这几行代码修复我的代码。这将在我们获取错误描述后发布error

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) 
     } 

    }