Objective-C中的自定义init方法,如何避免递归? [英] Custom init method in Objective-C, how to avoid recursion?

查看:117
本文介绍了Objective-C中的自定义init方法,如何避免递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个UINavigationController的子类,它始终以同一个根控制器开头。没有什么特别的,所以(对我来说)它是完全有意义重写init方法像这样:

   - (id) 
rootController = [[MyController alloc] init];

if(self = [super initWithRootViewController:rootController]){
//做一些更多的初始化
}

return self;
}



这显然会产生一个问题,因为[super initWithRootViewController]会调用[UINavigationController init ],这当然是我们覆盖的init方法,所以会发生无限递归。



我不想创建一个不同名称的init方法,如initCustom 。



目前我只能找到一个解决方案,但我真的很讨厌这种黑客:

   - (id)init {
if(initCalled)
return self;

initCalled = YES;

rootController = [[MyController alloc] init];

if(self = [super initWithRootViewController:rootController]){
//做一些更多的初始化
}

return self;
}

所以我的问题是:

编辑:原因为什么我想这样做,正如我在下面的一个意见中看到的:



我想创建一个总是以特定的视图控制器开始的导航控制器。我想要隐藏这个从类的消费者。不需要暴露不需要曝光的东西。让生活更容易,代码更清晰(封装被发明的原因之一,对吗?)

解决方案

所有UINavigationController不是用于子类化。



无论如何,最简单的方法是重写 initWithRootViewController:

   - (id)initWithRootViewController:(UIViewController)viewController {
return [super initWithRootViewController:[[[MyController alloc] init] autorelease]
}

你最好不要自动释放MyController,


I want to create a subclass of UINavigationController which always starts with the same root controller. Nothing special, so (to me) it makes perfect sense to override the init method like this:

- (id) init {
   rootController = [[MyController alloc] init];

   if (self = [super initWithRootViewController:rootController]) {
       // do some more initialization
   }

   return self;
}

This obviously creates a problem, because [super initWithRootViewController] will call [UINavigationController init], which is of course our overridden init method, so infinite recursion will occur.

I don't want to create an init method with a different name like "initCustom".

There's currently only one solution I can come up with, but I really hate this kind of hack:

- (id) init {
   if (initCalled)
       return self;

   initCalled = YES;

   rootController = [[MyController alloc] init];

   if (self = [super initWithRootViewController:rootController]) {
       // do some more initialization
   }

   return self;
}

So my question is: is there a better way of handling this? I'm sure I'm missing something very obvious, but I don't see it.

EDIT: The reason why I want to do this, as can be seen in one of my comments below:

I want to create a navigation controller that always starts with a specific view controller. I want to hide this from the consumer of the class. No need to expose things that don't need exposing. Makes life a lot easier, and code a lot cleaner (one of the reasons encapsulation was invented, right?)

解决方案

First of all UINavigationController is not intended for subclassing.

Anyway, the simplest way to do that is to override initWithRootViewController:

- (id) initWithRootViewController:(UIViewController) viewController {
   return [super initWithRootViewController:[[[MyController alloc] init] autorelease]];
}

You better don't autorelease MyController, but you understand the idea...

这篇关于Objective-C中的自定义init方法,如何避免递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆