Objective c 在init上返回其他对象

Objective c 在init上返回其他对象,objective-c,initialization,Objective C,Initialization,我在很多地方读到过,您应该总是像这样初始化Objective-C对象: - (id) init { if (self = [super init]) { .... } return self; } 因为super的init方法可能会从当前的self返回一个单独的对象 现在我正在尝试做类似的事情,我不确定我是否正确,相对于保留和释放应该如何工作: - (id) init:(int)idx { id obj = [Cache findSelf:idx

我在很多地方读到过,您应该总是像这样初始化Objective-C对象:

- (id) init {
    if (self = [super init]) {
        ....
    }
    return self;
}
因为super的
init
方法可能会从当前的
self
返回一个单独的对象

现在我正在尝试做类似的事情,我不确定我是否正确,相对于保留和释放应该如何工作:

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

我很好奇这是否是保存和释放
self
obj
的正确方法。有更好的方法吗?

关于
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
逻辑更加清晰


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

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

事实上,我的缓存是一个静态变量,但它并不像这里看到的那么简单;对象本身是一个抽象类,多个项可以具有相同的索引,因此我实际上要传入对象本身,它比较索引和类类型以找到正确的对象。每个子类都有一个单独的列表,但是集群是打破这个惯例的一个很好的理由。