为什么这是 CTFrame 的过度发布
在 iOS 上使用一些 CoreText 代码时,我很困惑为什么这是 CTFrame 的过度发布。我已经确认它是过度发布,但我感到困惑,因为它是使用 create
方法创建的。
for (NSValue *value in [self frameArray]) {
CGRect column = [value CGRectValue];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, column);
CTFrameRef frame = CTFramesetterCreateFrame(bodyFramesetter, CFRangeMake(position, 0), path, NULL);
CTFrameDraw(frame, context);
position += CTFrameGetVisibleStringRange(frame).length;
CGPathRelease(path);
// ???: Why does this cause an overrelease?
//CFRelease(frame);
}
更新
代码库是3.2,并且在第一个版本中不会发生崩溃。它在绘制视图时的某个时刻“随机”发生。您可能会猜到,这个循环位于视图的 -drawRect:
中。此应用程序中没有多线程。
Working with some CoreText code on iOS and I am confused as to why this is an overrelease of the CTFrame. I have confirmed it is an over-release but I am baffled because it is created with a create
method.
for (NSValue *value in [self frameArray]) {
CGRect column = [value CGRectValue];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, column);
CTFrameRef frame = CTFramesetterCreateFrame(bodyFramesetter, CFRangeMake(position, 0), path, NULL);
CTFrameDraw(frame, context);
position += CTFrameGetVisibleStringRange(frame).length;
CGPathRelease(path);
// ???: Why does this cause an overrelease?
//CFRelease(frame);
}
Update
The code base is 3.2 and the crash does not occur on the first release. It occurs "randomly" at some point while drawing the view. This loop, as you can probably guess is in the -drawRect:
of the view. There is no multi-threading in this application.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事实证明,Jason 的思路是正确的,问题是向
CTFramesetterCreateFrame
函数传递一个空框架设置器,然后该函数返回 NULL。Turns out that Jason was on the right track and that the issue was passing in a empty framesetter to the
CTFramesetterCreateFrame
function which then returned NULL.这是因为您的
drawRect:
方法在运行循环结束时被调用。这就是您的应用程序随机崩溃的原因。因此,您的解决方案是创建到
CTFrame
对象的全局链接,并仅在dealloc
中以及创建其他CTFrame
对象时释放该对象(并且替换您的全局链接)。That's because your
drawRect:
method gets called in the end of run loop. That's why your app crashes randomly.So your solution is to create global link to
CTFrame
object and release that object only indealloc
and when you're creating otherCTFrame
object (and replacing your global link).