我有这段代码:
- (CGImageRef)createImageWithContext:(CGContextRef)context
{
return CGBitmapContextCreateImage(context);
}
- (void)fooWithContext:(CGContextRef)context
{
CGImageRef imgRef = [self createImageWithContext:context];
CGImageRelease(imgRef);
}
这是一个在Xcode中构建的Objective-C项目,启用了ARC。构建和分析报告两个错误:一个在CGBitmapContextCreateImage行上标识潜在的泄漏,一个在CGImageRelease上,注意到“调用者此时不拥有的对象的引用计数的不正确减少”。
如果我将这两个功能合并为一个:
- (void)fooWithContext:(CGContextRef)context
{
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGImageRelease(imgRef);
}
我没有收到任何警告。
静态代码分析错误?或者我在这里遗漏了什么?
答案 0 :(得分:9)
根据标准的Cocoa命名约定,以单词create
开头的方法应返回非拥有引用。您正在返回一个保留的对象,但您应该返回一个未保留的对象。因此,当分析器查看-createImageWithContext:
时,它会看到假定返回一个非保留对象,但实际上是返回一个保留对象。因此第一次警告。
在-fooWithContext:
中,它会查看您的代码并说“嘿,根据我的命名惯例,createImageWithContext:
应该返回一个非拥有的引用。但是后来他们发布的内容不是拥有!那太糟糕了!“因此第二次警告。
您可以通过将-createImageWithContext:
的名称更改为以new
开头的内容(例如-newImageWithContext:
)来解决此问题。或者您可以使用cf_returns_retained
macro注释该方法,以向静态分析器指示该方法正在返回一个拥有的引用。
答案 1 :(得分:0)
我认为这是一种“误报”,这真的很有意义:
分析器不知道createImageWithContext:
中的返回值是否必须被释放(您可能会在之后未执行createImageWithContext:
的其他地方调用CGImageRelease
),也不知道是否知道imgRef
中的fooWithContext:
已被正确保留。
我的2美分:)