Я вижу большую утечку памяти при создании изображений путем визуализации невидимого представления в контексте. Я сократил его до самой базовой реализации и определил две строки кода, которые способствуют утечке памяти: renderInContext
и UIImagePNGRepresentation
. Если я прокомментирую обоим, утечки не произойдет, но если один из них раскоментирован, произойдет утечка, если обе раскоментированы, произойдет два утечки. Каждый раз, когда использует метод ниже, использование памяти значительно увеличивается (как и ожидалось), а затем через некоторое время оно уменьшается, но на 0,8 МБ выше, чем сумма, которая была до вызова.Утечка памяти с renderInContext и UIImagePNGRпредставляет
Как я могу решить эту проблему, чтобы не было утечек памяти?
public class func imageDataForSymbol(symbol: String) -> NSData? {
var imageData: NSData!
let dimension = 180
let label = UILabel(frame: CGRectMake(0, 0, CGFloat(dimension), CGFloat(dimension)))
label.text = symbol
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGImageAlphaInfo.PremultipliedLast.rawValue
let bitmapContext = CGBitmapContextCreate(nil, dimension, dimension, 8, 0, colorSpace, bitmapInfo)!
label.layer.renderInContext(bitmapContext) //FIXME: causing leak!!
let cgImage = CGBitmapContextCreateImage(bitmapContext)!
let image = UIImage(CGImage: cgImage)
imageData = UIImagePNGRepresentation(image)! //FIXME: causing leak!!
return imageData
}
Чтобы проверить это, в viewDidAppear
:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
NSData *d = [ImageGenerator imageDataForSymbol:@"W"];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"triggered");
});
});
});
Если есть лучший способ создать NSData
для Образом UILabel
«s layer
, я все для этого. Я не мог придумать другой способ его получить, кроме создания CIImage
от CGImage
, затем от CIImage
до UIImage
, затем от UIImage
до NSData
. Обратите внимание, что он не должен быть быстрым, но ему нужно создать изображение в фоновом потоке, чтобы пользовательский интерфейс оставался чувствительным к дополнительным вводам.
Использование Simulator @ Matt, попытается режим выхода на IPad в немного и доложить! Это не так странно, как кажется, я делаю больше причудливых вещей, кроме одного ярлыка, это урезанный код, который показывает утечки. Я бы просто сделал это так, как обычно, но возиться с UIKit в фоновом потоке - это большой нет-нет, и мне нужно, чтобы приложение продолжало реагировать, когда это происходит. – Joey
@matt Подход 'UIGraphicsBeginImageContext' был подход, который я взял изначально, но это не должно выполняться в фоновом потоке, и я не могу запустить его в основном потоке - см. Вопрос, связанный ниже. Подход, который я сейчас принимаю, - это подход, показанный в ответе: вместо этого используйте Core Graphics. http://stackoverflow.com/questions/12843777/renderincontext-memory-leak-if-not-use-on-main-thread/ – Joey
Рендеринг метки в контексте UIGraphics в фоновом потоке не работает ... текст не появляется. http://stackoverflow.com/questions/30512053/swift-uilabel-text-not-renderer-when-using-renderincontext-asynchronously – Joey