我正在考虑以下自定义视图控制器:
- (id)init
{
self = [super init];
if (self == nil) {
return self;
}
return [[UINavigationController alloc] initWithRootViewController:[self autorelease]];
}
这可以吗?
答案 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;
}