有 - (id)init不回归自己的​​好习惯吗?

时间:2012-08-24 04:14:23

标签: objective-c uiviewcontroller init

我正在考虑以下自定义视图控制器:

- (id)init
{
    self = [super init];
    if (self == nil) {
        return self;
    }
    return [[UINavigationController alloc] initWithRootViewController:[self autorelease]];
}

这可以吗?

3 个答案:

答案 0 :(得分:5)

这是非常糟糕的做法。初始化方法应返回正在实例化的类的实例。总是。或nil如果出现问题。

如果你想做一些额外的逻辑并返回一个导航控制器,当前的类视图控制器作为根视图控制器你应该考虑做一个类方法,如:

+ (UINavigationController*)someThing{
    id IdontKnowWhatIsTheNameOfYourClass = [[[[self class] alloc] init] autorelease];
    return [[[UINavigationController alloc] initWithRootViewController:IdontKnowWhatIsTheNameOfYourClass] autorelease];
}

但即使这不是好习惯。您的视图控制器应该知道它是模态视图控制器,导航控制器内部还是标签栏控制器内部。即使你可以说你只会使用那种方法,它应该是任何这些段的根。

要明确,这将有效。但这非常糟糕。

答案 1 :(得分:0)

这取决于一些事情。从技术上讲,允许init方法重新分配self(这就是为什么你总是在同一个赋值中配对alloc / init)。但是,应该被认为是一个糟糕的设计来返回一个不同类的对象(即一个不从init'd类继承的对象)。

所以,除非你的类是UINavigationController的,否则我会说你的init方法是一个糟糕的选择。

最好创建一个更语义命名且具有适当返回类型的类方法(而不是init使得它将在类的同一族中返回一个对象的隐式契约。它叫做。

答案 2 :(得分:0)

如果你有充分的理由这样做是很好的做法。它由Class clusters使用或在尝试使用棘手的缓存机制时使用。这样做的理由很少,而且是非常先进的事情。如果你有一个非常复杂的超类,这也很危险。

如果你真的必须使用这个技巧(而不仅仅是利用类构造函数),你必须小心尊重引用计数(如果你没有使用ARC):

  • 发布以前的自我实例

  • 确保新返回的自己有一个+1保留计数,因为您的客户端会在完成后将其释放。

E.g。如果你想使用一些实例缓存:

- (id)initWithKey:(NSString *)aKey
{
    id cachedInstance = [__myCache objectForKey:aKey];
    if (cachedInstance) {
        // use this instance instead of self
        [self release];
        return [cachedInstance retain];
    }
    self = [super init];
    if (self) {
        // further init the instance here
        ...
        // cache it
        [__myCache setObject:self forKey:aKey];
    }
    return self;
}