代码之家  ›  专栏  ›  技术社区  ›  Johannes Rudolph

指定的初始值设定项,保留参数?

  •  1
  • Johannes Rudolph  · 技术社区  · 15 年前

    我有以下指定的初始值设定项:

    -(id) initWithName:(NSString*)name;
    

    以及以下默认初始值设定项:

    -(id) init { return [self initWithName:@"foo"]; }
    

    指定的初始值设定项接收的对象类型是什么?释放还是自动释放?

    给定以下初始值设定项:

    -(id) init { return [self initWithName:[NSString new]]; }
    

    我会收到一个重定目标。默认初始值设定项将永远没有机会释放它,所以我不应该保留它?. 现在想象一下,这将是一个不提供便利初始值设定项的类,而不是nsstring(如-myclasswithparam:)。我需要提供一个方便的初始值设定项来启用就地构造吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Nikolai Ruhe    15 年前

    初始值设定项(无论是否指定)不应该关心它作为参数接收的对象的所有权。如果它想保留对象,那么无论参数来自何处,它都必须复制或保留对象。指定的初始值设定项 initWithName 应该抄袭 name 其实现中的参数。

    nsstring文本的内存管理是一种特殊情况,因为这些对象从未被释放,只是忽略了 retain , release autorelease .

    第三个示例有一个漏洞,因为名称参数字符串对象从未被释放。

        2
  •  0
  •   iKenndac    15 年前

    您应该始终将自动释放的对象(或在之后释放)发送给初始化程序-此实例中的内存管理规则不会更改。

    在你的例子中,我会这样做:

    -(id) init {return [self initWithName:[[NSString new] autorelease]]]}
    

    这将修复内存泄漏并允许就地构造。

    但是,在传递初始值设定项时不需要额外的保留-使用的是 self 很好。一般来说, +alloc 保留对象一次,并且 -init 方法不再保留。 -初始化 会被称为 [super init] 调用在类树上进行,但对象最终返回调用方时只应保留一次。- +OLLC 已经为你做过了。

    然而, 方便 方法 不要 包含词init、copy或new应返回一个自动释放的对象。举个例子:

    +(MyObject *)objectWithName:(NSString *)aName {
        return [[[MyObject alloc] initWithName:aName] autorelease];
    }
    

    fwiw,我通常将-in i t作为我指定的初始值设定项,因此如果我忘记了并将-in i t发送给一个对象(或者其他人也这样做),就不会得到垃圾对象。例如:

    -(id)init {
        if (self = [super init]) {
            [self setName:[[NSString new] autorelease]];
    
            myReallyImportantiVar = [[NSArray alloc] init];
            // etc;
        }
        return self;
    }
    
    
    -(id)initWithName:(NSString  *)aName {
        if (self = [self init]) {
            [self setName:aName];
        }
        return self;
    }
    

    这可能会稍微降低效率(当您使用-initwithname:,setname被调用两次),但这样更安全。