Ios CTFramesetterCreateWithAttributedString导致内存泄漏

Ios CTFramesetterCreateWithAttributedString导致内存泄漏,ios,memory-leaks,core-text,Ios,Memory Leaks,Core Text,我不知道为什么这段简单的代码有时会导致内存泄漏,但并非总是如此 这段代码包装在NSOperation中,并在NSOperationQueue队列中运行。 该操作将修剪sourceNSAString以适应某些大小,并将其返回到其他线程 //sourceNSAString is a NSMutableAttributedString that will be set to nil elsewhere in another GCD queue. CTFramesetterRef frameSetter

我不知道为什么这段简单的代码有时会导致内存泄漏,但并非总是如此

这段代码包装在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不能在后台线程中使用


有什么想法吗?谢谢

我认为应该在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);

这应该可以正常工作,好吧,至少现在看来这是一个模拟器错误。我在一台设备上分析了我的应用程序,内存泄漏就消失了。在多线程环境中使用核心文本时,模拟器似乎存在大量内存泄漏。例如,创建一个CTFrameSetter,稍后在相同的GCD串行队列中释放它,这是根据文档允许的,可能会随机导致内存泄漏。无论如何,当在真实设备中分析时,所有这些内存泄漏都会消失。

此泄漏不仅仅是一个模拟器错误,它会出现在实际设备上。有关深入调试的信息,请参见我对这个相关问题的回答

,但如果frameSetter为false,则无需释放NULL ref,对吗?如果它是真的,它将被完全释放。更重要的是,如果它为NULL,那么CFRelease将崩溃,所以您必须再次检查NULL。原始代码正确。有关根本原因,请参阅。