用于分配初始化程序的Cocoa命名方案

mxc*_*xcl 4 cocoa naming-conventions

出于某种原因,我认为这在内存管理命名规则下是有效的:

Bar *bar = [Bar new];
[Foo fooWithNewBar:bar];
// no need to release bar, foo took ownership
Run Code Online (Sandbox Code Playgroud)

但是现在我正在进行静态分析,它认为每次我这样做都会有潜在的泄漏.

我看到__attribute((ns_consumed))我可以在fooWithNewBar声明中使用它.但是Xcode 4.0.1的Clang还不支持这个属性.

那么,没有这样的命名模式?

小智 5

我也认为ns_consumed在你的情况下没有对应的命名模式.命名模式很大程度上是由NeXTSTEP/Apple驱动的,我无法想象Apple框架中的方法与您想要的语义相同.

但请注意,您可以告诉Xcode使用支持该ns_consumed属性的更新版本的Clang Static Analyzer,该属性随checker-254一起发布.

我正在使用checker-256(今天发布,但任何版本> = 254应该可以工作)我刚试过以下内容:

// MyClass.h
#ifndef __has_feature      // Optional.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif

#ifndef NS_CONSUMED
#if __has_feature(attribute_ns_consumed)
#define NS_CONSUMED __attribute__((ns_consumed))
#else
#define NS_CONSUMED
#endif
#endif

@interface MyClass : NSObject {
@private
    NSString *_string;
}
+ (MyClass *)myClassWithNewStringConsumed:(NSString *) NS_CONSUMED string NS_RETURNS_RETAINED;
+ (MyClass *)myClassWithNewString:(NSString *)string NS_RETURNS_RETAINED;
@end
Run Code Online (Sandbox Code Playgroud)

// MyClass.m
#import "MyClass.h"

@implementation MyClass

+ (MyClass *)myClassWithNewStringConsumed:(NSString *)string {
    MyClass *o = [MyClass new];
    if (o) o->_string = string;
    return o;
}

+ (MyClass *)myClassWithNewString:(NSString *)string {
    MyClass *o = [MyClass new];
    if (o) o->_string = string;
    return o;
}

@end
Run Code Online (Sandbox Code Playgroud)

此代码为存储在s以下位置的字符串的潜在泄漏提供静态分析器警告:

// SomewhereElse.m
NSString *s = [[NSString alloc] initWithFormat:@"%d",
    [[NSProcessInfo processInfo] processIdentifier]];
MyClass *o = [MyClass myClassWithNewString:s];
[o release];
Run Code Online (Sandbox Code Playgroud)

而这个使用带有ns_consumed属性的方法参数的代码不会给出静态分析器警告:

// SomewhereElse.m
NSString *s = [[NSString alloc] initWithFormat:@"%d",
    [[NSProcessInfo processInfo] processIdentifier]];
MyClass *o = [MyClass myClassWithNewStringConsumed:s];
[o release];
Run Code Online (Sandbox Code Playgroud)