抱歉有关iPhone和Quartz编程的愚蠢问题。刚刚开始从C ++转换到Objective-C:)
所以,我有这样一个类方法
+(CGGradientRef)CreateGradient:(UIColor*)startColor endColor:(UIColor*)endColor
{
CGGradientRef result;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[2] = {0.0f, 1.0f};
CGFloat startRed, startGreen, startBlue, startAlpha;
CGFloat endRed, endGreen, endBlue, endAlpha;
[endColor getRed:&endRed green:&endGreen blue:&endBlue alpha:&endAlpha];
[startColor getRed:&startRed green:&startGreen blue:&startBlue alpha:&startAlpha];
CGFloat componnents[8] = {
startRed, startGreen, startBlue, startAlpha,
endRed, endGreen, endBlue, endAlpha
};
result = CGGradientCreateWithColorComponents(colorSpace, componnents, locations, 2);
CGColorSpaceRelease(colorSpace);
return result;
}
及其用法。
-(void)FillGradientRect:(CGRect)area startColor:(UIColor *)startColor endColor:(UIColor *)endColor isVertical:(BOOL)isVertical
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
CGGradientRef gradient = [Graphics CreateGradient:startColor endColor:endColor];
CGPoint startPoint, endPoint;
if (isVertical) {
startPoint = CGPointMake(CGRectGetMinX(area), area.origin.y);
endPoint = CGPointMake(startPoint.x, area.origin.y + area.size.height);
}else{
startPoint = CGPointMake(0, area.size.height / 2.0f);
endPoint = CGPointMake(area.size.width, startPoint.y);
}
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
UIGraphicsPopContext();
}
一切都按预期工作。但是,当我从Xcode 4运行Analyze工具时,我在result
变量的方法 CreateGradient 中收到有关内存泄漏的警告。好吧,我理解那是什么,但在我的调用方法中,我正在释放渐变对象(CGGradientRelease(gradient);
)。
那么,谁错了,如何让Analyze工具开心?
THX
答案 0 :(得分:1)
由于CGGradientRef是Core Foundation类型的对象,因此您可以自动释放它。只需在返回渐变之前添加此行:
[(id)result autorelease];
答案 1 :(得分:0)
如果目标只是让分析仪在ARC中保持满意,那么只需将其设为C函数而不是目标C,即:
CGGradientRef CreateGradient(UIColor *startColor, UIColor * endColor)
然后应用Core Foundation命名方案,该方案表示名称中包含Create的函数被视为返回保留对象(调用者有责任释放它)。这满足了分析仪。
如果你想要一个自动释放的变量,那么将CG类型的所有权转移到ARC:
id arc_result = (__bridge_transfer id)result
但是,如果这样做,则需要返回objective-c类型(arc_result),而不是CG类型。如果返回CG类型,则不会保留对arc_result的引用,因此编译器会在您从函数返回时将其清理。
您可以使用此hack来实现CG类型的自动释放:
dispatch_async(dispatch_get_main_queue(), ^{
CGGradientRelease(result);
});
它会满足分析仪并可能工作 - 虽然我认为它非常不安全!