Art*_*sev 5 core-graphics objective-c core-foundation ios automatic-ref-counting
我有一个ARC项目,我正在尝试绘制垂直线性渐变.下面的代码适用于模拟器,但EXC_BAD_ACCESS在设备上进行测试时会抛出内存/ 错误.该应用程序使用以下两行代码崩溃:
NSArray *colorArray = [NSArray arrayWithObjects:(__bridge id)topColor, (__bridge id)bottomColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colorArray, colorLocations);
Run Code Online (Sandbox Code Playgroud)
这两行代码取自以下代码(供参考):
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
[self createGradientForContext:context andView:self.captionView];
[self createGradientForContext:context andView:self.linksView];
[self createGradientForContext:context andView:self.commentView];
}
- (void)createGradientForContext:(CGContextRef)context andView:(UIView *)view
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat colorLocations[] = { 0.0f, 1.0f };
CGColorRef topColor = [[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor];
CGColorRef bottomColor = [[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor];
NSArray *colorArray = [NSArray arrayWithObjects:(__bridge id)topColor, (__bridge id)bottomColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge_retained CFArrayRef) colorArray, colorLocations);
CGRect frame = view.frame;
CGPoint startPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMinY(frame));
CGPoint endPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMaxY(frame));
CGContextSaveGState(context);
CGContextAddRect(context, frame);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
Run Code Online (Sandbox Code Playgroud)
提前感谢任何和所有指导.
现在解释你崩溃的原因......
问题是这两行:
Run Code Online (Sandbox Code Playgroud)CGColorRef topColor = [[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor]; CGColorRef bottomColor = [[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor];
这是一个非常普遍的问题; 关于Stack Overflow的问题有很多被这个问题所困扰的用户.
问题是因为那些UIColor对象永远不会在这些行之后被引用,ARC会立即释放它们 - 因为这些UIColor对象是CGColor对象的唯一所有者,所以UIColors会立即释放CGColors,留下两个死CGColor对象.然后你尝试放入一个数组.
正如您所发现的,从NSArray切换到纯CFArray无法解决这个问题.从UIColor切换到纯CGColor是一种解决方案; 另一种是将自己的所有权放在CGColors上:
CGColorRef topColor = CGColorRetain([[UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f] CGColor]);
CGColorRef bottomColor = CGColorRetain([[UIColor colorWithRed:48.0f/255.0f green:48.0f/255.0f blue:48.0f/255.0f alpha:1.0f] CGColor]);
?
CGColorRelease(topColor);
CGColorRelease(bottomColor);
Run Code Online (Sandbox Code Playgroud)
尝试使用a CFArrayRef并避免桥接,看看它是否有所作为.
CGFloat topColorComps[] = {51.0f/255.0f, 51.0f/255.0f, 51.0f/255.0f, 1.0f};
CGFloat bottomColorComps[] = {48.0f/255.0f, 48.0f/255.0f, 48.0f/255.0f, 1.0f};
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGColorRef topColor = CGColorCreate(rgb, topColorComps);
CGColorRef bottomColor = CGColorCreate(rgb, bottomColorComps);
CGColorSpaceRelease(rgb);
CFMutableArrayRef colorArray = CFArrayCreateMutable(NULL, 2, &kCFTypeArrayCallbacks);
CFArrayAppendValue(colorArray, topColor);
CFArrayAppendValue(colorArray, bottomColor);
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colorArray, colorLocations);
CFRelease(colorArray);
CFRelease(topColor);
CFRelease(bottomColor);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2976 次 |
| 最近记录: |