我不知道为什么这段简单的代码有时会导致内存泄漏(并非总是如此)。
这段代码包含在NSOperation中,并在NSOperationQueue队列中运行。 该操作将修剪sourceNSAString以适合某种大小,并将其作为结果返回给其他线程。
//sourceNSAString is a NSMutableAttributedString that will be set to nil elsewhere in another GCD queue.
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) sourceNSAString);
if (frameSetter) {
CFRange fitRange = {static_cast<CFIndex>(range.location), 0};
CFRange totalRange = {static_cast<CFIndex>(range.location), static_cast<CFIndex>(range.length)};
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, totalRange, NULL, size, &fitRange);
CFRelease(frameSetter);
...... trim sourceNSAString to fit in fitRange
}
是因为: 1,我不应该将sourceNSAString返回给另一个线程?要么 2,CTFramesetterCreateWithAttributedString不能在后台线程中使用?
有什么想法吗?谢谢!
答案 0 :(得分:0)
好吧,这似乎是一个模拟器错误(至少目前为止)。我在设备上分析了我的应用程序,内存泄漏就消失了。在多线程环境中使用核心文本时,模拟器似乎有很多内存泄漏。例如,创建一个CTFrameSetter并稍后在同一个GCD串行队列中释放它(根据Doc允许)可能导致内存随机泄漏。无论如何,当在真实设备中进行分析时,所有这些内存泄漏都会消失。
答案 1 :(得分:0)
这个泄漏不仅仅是一个模拟器错误,它出现在实际的设备上。有关深入调试Memory usage grows with CTFontCreateWithName and CTFramesetterRef
,请参阅我对此相关问题的回答答案 2 :(得分:-2)
我认为你应该在if语句之后释放frameSetter,因为如果没有执行if语句,则frameSetter不会被释放。
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) sourceNSAString);
if (frameSetter) {
CFRange fitRange = {static_cast<CFIndex>(range.location), 0};
CFRange totalRange = {static_cast<CFIndex>(range.location), static_cast<CFIndex>(range.length)};
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, totalRange, NULL, size, &fitRange);
}
CFRelease(frameSetter);
这应该有效