2

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

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

这个可以吗?

4

3 回答 3

5

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

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

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

但即使这样也不是好的做法。您的视图控制器应该不知道它是模式视图控制器、导航控制器内部还是选项卡栏控制器内部。即使你可以争辩说你只会在它应该是任何这些 segues 的根源的情况下使用该方法。

需要明确的是,这将起作用。但这非常糟糕。

于 2012-08-24T04:26:31.740 回答
0

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

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

  • 释放之前的 self 实例

  • 确保新返回的 self 具有 +1 保留计数,因为您的客户希望在完成后释放它。

例如,如果你想使用一些实例缓存:

- (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;
}
于 2012-08-24T05:48:48.827 回答
0

这取决于几件事。从技术上讲,init 方法可以重新分配self(这就是为什么您总是在同一个分配中配对 alloc/init)。然而,返回不同类的对象(即不从被初始化的类继承的对象)应该被认为是糟糕的设计。

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

最好创建一个在语义上更命名并具有适当返回类型的类方法(而不是隐式约定,init它会返回一个与调用它的类同族的对象。

于 2012-08-24T04:29:46.747 回答