石英 2D 绘图崩溃

Posted

技术标签:

【中文标题】石英 2D 绘图崩溃【英文标题】:Quartz 2D Drawing Crashing 【发布时间】:2013-02-01 15:33:28 【问题描述】:

我不知道为什么它会停止工作,但是当我尝试绘制它的任何部分时,这段代码会导致我的设备崩溃。我是核心图形的新手,所以任何指针或建议都会有很大帮助。谢谢!

// Style
CGContextRef context = UIGraphicsGetCurrentContext();

// Colors
CGColorRef fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0].CGColor;
CGColorRef fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0].CGColor;

CGRect box = CGRectMake(5, 5, self.frame.size.width - 10, self.frame.size.height - 10);
// Shadow
CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 1.0, fillBoxShadow);
CGContextAddRect(context, box);
CGContextFillPath(context);
// Box
CGContextSetFillColorWithColor(context, fillBox);
CGContextAddRect(context, box);

CGContextFillPath(context);

【问题讨论】:

【参考方案1】:

如果您的项目使用 ARC,那么这两行可能是您的问题的一部分:

CGColorRef fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0].CGColor;
CGColorRef fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0].CGColor;

ARC 正在释放 UIColor 对象,从而释放 CGColorRef。您需要保留 CGColorRef,然后在完成后释放它。

我会这样写代码:

UIColor *fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0];
UIColor *fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0];

然后在方法中使用 fillBox.CGColor 和 fillBoxShadow.CGColor。

【讨论】:

它不会立即释放,而是在 runloop 结束时:colorWithRed... 是一个工厂方法,它返回一个自动释放的对象。它们在 @autorelease 块的末尾或 runloop 迭代之后释放。所以这不是问题的根源。 求不同。 ARC 将在CGRect box = CGRectMake(...); 代码之前释放 UIColor 对象。很多个月前,我在将现有项目转换为 ARC 时遇到了这个问题...... 否定。刚刚尝试了我的一段代码:CGColorRef white = [UIColor whiteColor].CGColor; CGContextClearRect(ctx, rect); CGContextSetFillColorWithColor(ctx, white); CGContextAddPath(ctx, _bezier.CGPath); CGContextFillPath(ctx);,它在 ARC 中完美运行。 UIColor 对象恰好在内存中的同一个地方。如果启用 NSZombie,您将看到该对象已被释放。见blog.bignerdranch.com/… 或***.com/questions/9218664/… 我没有看到启用僵尸有任何问题,静态分析器也没有告诉我这有潜在危险。即使你是对的,这也不是导致崩溃的原因。【参考方案2】:

而不是做

CGContextAddRect(context, box);
CGContextFillPath(context);

尝试使用CGContextFillRect

您无法填充未事先添加到上下文中的路径。

注意:你可以这样做

CGContextAddPath(context, [UIBezierPath pathWithRect:box].CGPath);
CGContextFillPath(context);

但这与仅仅填充一个矩形相比有点矫枉过正。

(不确定pathWithRect: 语法,但它存在。)

【讨论】:

CGContextAddRect 将矩形添加到上下文的当前路径。这样做的两种方法是等效的。不过,我确实同意CGContextFillRect 更简单,因此在没有其他任何东西可以在相同的填充中绘制时更好。

以上是关于石英 2D 绘图崩溃的主要内容,如果未能解决你的问题,请参考以下文章

石英 2D 锯齿线

石英 2D 或 OpenGL ES?从长远来看的利弊,迁移到其他平台的可能性

canvas 2D绘图

绘图与滤镜全面解析--Quartz 2D Core Image

用于linux的c++ 2d绘图工具

ios绘图之quarz2d