用于分配初始值设定项的可可命名方案

| 由于某种原因,我认为这在内存管理命名规则下是有效的:
Bar *bar = [Bar new];
[Foo fooWithNewBar:bar];
// no need to release bar, foo took ownership
但是,现在我正在执行静态分析,它认为每次执行此操作时都可能存在泄漏。 我看到可以在
fooWithNewBar
声明中使用
__attribute((ns_consumed))
。但是Xcode 4.0.1 \的Clang尚不支持此属性。 那么,没有这样的命名模式吗?     
已邀请:
我也认为您的情况下没有对应于ѭ3的命名模式。命名模式主要是由NeXTSTEP / Apple驱动的,我想不出Apple框架中具有所需语义的方法。 但是请注意,您可以告诉Xcode使用支持
ns_consumed
属性的更新版本的Clang静态分析器,该属性是由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
// 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
这段代码为静态分析器警告了存储在
s
中的字符串的潜在泄漏:
// SomewhereElse.m
NSString *s = [[NSString alloc] initWithFormat:@\"%d\",
    [[NSProcessInfo processInfo] processIdentifier]];
MyClass *o = [MyClass myClassWithNewString:s];
[o release];
而此代码使用具有
ns_consumed
属性的method参数的代码,则不会发出静态分析器警告:
// SomewhereElse.m
NSString *s = [[NSString alloc] initWithFormat:@\"%d\",
    [[NSProcessInfo processInfo] processIdentifier]];
MyClass *o = [MyClass myClassWithNewStringConsumed:s];
[o release];
    
没有这样的模式。无论我在哪里读到的内容,我都没有。     
Bar *bar = [Bar new];
你自己吧。
[Foo fooWithNewBar:bar];
如果这要拥有酒吧,则应保留它。那并不会放弃您的所有权,因此您仍然必须释放酒吧。 我从未见过您使用的模式。     
Foo对Bar感兴趣,但是* bar仍然有兴趣,直到
[bar release]
为止。     
Objective-C参考计数内存管理的所有权是C ++
share_ptr
,而不是
auto_ptr
样式。换句话说,您不会将所有权转让给“ 16”实例。相反,
Foo
实例在您的
Bar
实例中声明了ownerhsip的份额(也让您,
[Bar new]
的调用者也拥有所有权)。在释放实例之前,您始终需要放弃实例的所有权份额。因此,您的示例应为
Bar *bar = [[Bar alloc] init]; //Most Obj-C devs prefer alloc/init. When in Rome...
[Foo fooWithNewBar:[bar autorelease]]; //relinquish ownership of bar
请注意,您必须使用
-autorelease
而不是
-release
放弃您的所有权份额,因为
Foo
需要有机会在ѭ24chance被释放之前要求所有权。     

要回复问题请先登录注册