我的代码中有内存泄漏,我无法解决问题。具体来说,我在这一行得到一个EXC_BAD_ACCESS(代码= 1):
CGFloat xStart = origin.x + CTLineGetOffsetForStringIndex(line, index, NULL);
在以下代码中:
- (CGRect)firstRectForNSRange:(NSRange)range;
{
NSInteger index = range.location;
NSArray *lines = (__bridge NSArray *) CTFrameGetLines(self.textFrame);
NSInteger linesCount = [lines count];
CFIndex paragraphSpacingOffset = (self.paragraphSpacing > 0) ? 1 : 0;
for (NSInteger i = 0 + paragraphSpacingOffset; i < (linesCount - paragraphSpacingOffset); i++)
{
CTLineRef line = (CTLineRef) CFBridgingRetain([lines objectAtIndex:i]);
CFRange lineRange = CTLineGetStringRange(line);
NSInteger localIndex = index - lineRange.location;
if (localIndex >= 0 && localIndex < lineRange.length)
{
NSInteger finalIndex = MIN(lineRange.location + lineRange.length, range.location + range.length);
CGPoint origin;
CTFrameGetLineOrigins(self.textFrame, CFRangeMake(i, 0), &origin);
CGFloat xStart = origin.x + CTLineGetOffsetForStringIndex(line, index, NULL);
CGFloat xEnd = origin.x + CTLineGetOffsetForStringIndex(line, finalIndex, NULL);
CGFloat ascent, descent;
CTLineGetTypographicBounds(line, &ascent, &descent, NULL);
CFRelease(line);
return CGRectMake(xStart, origin.y - descent, xEnd - xStart, ascent + descent);
}
else
{
CFRelease(line);
}
}
return CGRectNull;
}
我几乎可以肯定这是内存泄漏,因为我已经彻底检查了代码。任何人都可以看到我如何管理上面的Core Foundation对象line
?当line
被发送到CTLineGetOffsetForStringIndex
我需要再次发布时,会发生什么事吗?
答案 0 :(得分:1)
你的问题几乎肯定在这里:
CTFrameGetLineOrigins(self.textFrame, CFRangeMake(i, 0), &origin);
这表示&#34;将来自索引i
的行原点通过帧结尾写入origin
指向的内存。&#34;不幸的是,origin
仅指向一个元素,因此您将遍布堆栈的其余部分。我怀疑你的意思是CFRangeMake(i, 1)
。
其他说明:
你在CFArray和NSArray之间移动创造了很多复杂性。如果你只使用CFArray,代码会简单得多:
CFArrayRef lines = CTFrameGetLines(self.textFrame);
CFIndex linesCount = CFArrayGetCount(lines);
...
CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(lines, i);
这样做,您不需要拨打CFRelease()
。您现在拨打CFRelease
的唯一原因是因为您正在调用CFBridgingRetain()
,这使得一切都变得比它需要的更复杂。有时候接触NSArray是一件非常棒的事情,但在这种情况下它并非如此。