在init上返回其他对象

时间:2009-07-24 16:06:07

标签: objective-c initialization

我在很多地方都读过你应该像这样初始化Objective-C对象:

- (id) init {
    if (self = [super init]) {
        ....
    }
    return self;
}

因为超级init方法可能会从当前self返回单独的对象。

现在我正在尝试做这样的事情,而且我不确定我是否正确,相对于保留和释放应该如何运作:

- (id) init:(int)idx {
    id obj = [Cache findSelf:idx];
    if (obj) {
        [self release];
        self = [obj retain];
    } else {
        self = [self doLoad];
    }
    return self;
}

如果这是保留和释放selfobj的正确方法,我很好奇。还有更好的方法吗?

2 个答案:

答案 0 :(得分:7)

你对self = [super init]部分是正确的,因为一些Cocoa类确实返回了与分配的对象不同的对象。但是,这是例外而不是规则,在您自己的代码中这样做应该是非常罕见或根本不做。虽然拦截-init调用可能很诱人,但是你会违背既定约定以及Objective-C程序员期望代码执行的操作。

这种类型的-init方法通常是一种糟糕的方法,因为-init方法应该尽可能简单,并且应该真正关注初始化对象。我可能会写一个像这样的便利方法:

+ (id) instanceForIndex:(NSUInteger)index {
    id obj = [Cache findSelf:index];
    if (obj == nil) {
      obj = [[self alloc] init];
      // Add to cache
    }
    return [[object retain] autorelease];
}

然后调用此方法而不是-init。这将使-init逻辑更清晰。

另外,我不确定你的Cache类是做什么的,但是值得重新考虑实现,并使用隐藏的静态变量来存储实例(例如,一个NSMutableDictionary,其中键是一个从索引创建的NSNumber)。 This SO question可能有用。

答案 1 :(得分:1)

我同意Quinn你应该使用便利类方法。尽管如此,我认为您的init方法大多是正确的,除了您需要调用父初始值设定项的else子句,即self = [super init]