Objective c 目标C:有条件创建对象的优雅解决方案?

Objective c 目标C:有条件创建对象的优雅解决方案?,objective-c,iphone,Objective C,Iphone,这是一个客观的C/iphone SDK问题 我有一个仪表板视图,用于切换到应用程序中的不同视图。从本质上说,视图有六个按钮,它们是指向不同视图的快捷方式 下面是按钮事件处理代码的示例: - (IBAction)moreButtonPressed:(id)sender{ // switch view here if(self._moreViewController == nil){ MoreViewController *moreViewController = [[MoreViewCon

这是一个客观的C/iphone SDK问题

我有一个仪表板视图,用于切换到应用程序中的不同视图。从本质上说,视图有六个按钮,它们是指向不同视图的快捷方式

下面是按钮事件处理代码的示例:

- (IBAction)moreButtonPressed:(id)sender{
 // switch view here
 if(self._moreViewController == nil){
  MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]];
  self._moreViewController = moreViewController;
  [moreViewController release];
 }

 [self SwitchView:self._moreViewController];
}
我可以为每个按钮复制此代码并更改相应的类(视图控制器类)),但我希望有一个更优雅的解决方案


有人知道怎么做吗?

一个简单的改进是在创建每个按钮时为其设置tag属性

- (IBAction)someButtonPressed:(id)sender{ // switch view here switch (sender.tag) { case 0: if(self._moreViewController == nil){ MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]]; self._moreViewController = moreViewController; [moreViewController release];} [self SwitchView:self._moreViewController]; break; case 1: if(self._lessViewController == nil){ MoreViewController *lessViewController = [[LessViewController alloc] initWithNibName:@"LessView" bundle:[NSBundle mainBundle]]; self._lessViewController = lessViewController; [lessViewController release];} [self SwitchView:self._lessViewController]; break; } } -(iAction)某些按钮按下:(id)发件人{ //在这里切换视图 开关(sender.tag){ 案例0: if(self.\u moreViewController==nil){ MoreViewController*MoreViewController=[[MoreViewController alloc]initWithNibName:@“MoreView”捆绑:[NSBundle mainBundle]]; self.\u moreViewController=moreViewController; [moreViewController发布];} [self SwitchView:self.\u moreViewController]; 打破 案例1: if(self.\u lessViewController==nil){ MoreViewController*lessViewController=[[lessViewController alloc]initWithNibName:@“LessView”捆绑:[NSBundle mainBundle]]; self.\u lessViewController=lessViewController; [lessViewController release];} [自切换视图:自切换控制器]; 打破 } }
这样你只有一个功能。不过,最好不要在case语句中重复代码,而只提供要实例化的类的参数。这不是我尝试过的。

一个简单的改进是在创建每个按钮时为其设置tag属性

- (IBAction)someButtonPressed:(id)sender{ // switch view here switch (sender.tag) { case 0: if(self._moreViewController == nil){ MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]]; self._moreViewController = moreViewController; [moreViewController release];} [self SwitchView:self._moreViewController]; break; case 1: if(self._lessViewController == nil){ MoreViewController *lessViewController = [[LessViewController alloc] initWithNibName:@"LessView" bundle:[NSBundle mainBundle]]; self._lessViewController = lessViewController; [lessViewController release];} [self SwitchView:self._lessViewController]; break; } } -(iAction)某些按钮按下:(id)发件人{ //在这里切换视图 开关(sender.tag){ 案例0: if(self.\u moreViewController==nil){ MoreViewController*MoreViewController=[[MoreViewController alloc]initWithNibName:@“MoreView”捆绑:[NSBundle mainBundle]]; self.\u moreViewController=moreViewController; [moreViewController发布];} [self SwitchView:self.\u moreViewController]; 打破 案例1: if(self.\u lessViewController==nil){ MoreViewController*lessViewController=[[lessViewController alloc]initWithNibName:@“LessView”捆绑:[NSBundle mainBundle]]; self.\u lessViewController=lessViewController; [lessViewController release];} [自切换视图:自切换控制器]; 打破 } }
这样你只有一个功能。不过,最好不要在case语句中重复代码,而只提供要实例化的类的参数。但我并没有尝试过这一点。

首先,使用如下代码将NIB的名称移动到ViewController类中:

- (MoreViewController *)init
{
    self = [super initWithNibName:@"MoreView" bundle:nil];
    if (self != nil)
    {
    }
    return self;
}
这将使视图控制器自包含,以便您可以干净地创建它们:

MoreViewController *moreViewController = [[MoreViewController alloc] init];
无论你做什么,我都推荐这种方法。苹果的示例代码尽管如此,在调用方中输入NIB的名称是愚蠢的。为什么视图控制器的每个调用方都需要知道这个内部实现细节

接下来,请记住ObjC是一种动态语言。可以根据对象的类名构造对象,如下所示:

Class vcClass = NSClassFromString([self.classNameForSender objectForKey:sender])
UIViewController *vc = [[[vcClass alloc] init] autorelease];
[self switchToView:vc];
在上面的例子中,
-classNameForSender
是一个将按钮对象映射到类名的
NSDictionary
,但是您当然可以通过许多其他方式获得这些类名。根据发送者的不同,您可能能够将类直接挂起到发送者上(尽管这对于标准
UIControl
s很困难,因为它们只有一个整数
标签

我没有复制你将VC存储到ivar中。你真的需要这个吗?如果是这样,您可以按名称将其存储在字典中,也可以将所有VCs存储在
NSMutableSet
中。但在大多数情况下,您确实不需要它,因为大多数UI控制器(如NavController)将为您管理内存


另一种动态性较差的方法是在开始时创建所有视图控件并将它们放入字典中,然后您可以根据发送方将它们从字典中加载。这具有更好的编译时检查的优点,但会占用更多内存。

首先,使用如下代码将NIB的名称移动到ViewController类中:

- (MoreViewController *)init
{
    self = [super initWithNibName:@"MoreView" bundle:nil];
    if (self != nil)
    {
    }
    return self;
}
这将使视图控制器自包含,以便您可以干净地创建它们:

MoreViewController *moreViewController = [[MoreViewController alloc] init];
无论你做什么,我都推荐这种方法。苹果的示例代码尽管如此,在调用方中输入NIB的名称是愚蠢的。为什么视图控制器的每个调用方都需要知道这个内部实现细节

接下来,请记住ObjC是一种动态语言。可以根据对象的类名构造对象,如下所示:

Class vcClass = NSClassFromString([self.classNameForSender objectForKey:sender])
UIViewController *vc = [[[vcClass alloc] init] autorelease];
[self switchToView:vc];
在上面的例子中,
-classNameForSender
是一个将按钮对象映射到类名的
NSDictionary
,但是您当然可以通过许多其他方式获得这些类名。根据发送者的不同,您可能能够将类直接挂起到发送者上(尽管这对于标准
UIControl
s很困难,因为它们只有一个整数
标签

我没有复制你将VC存储到ivar中。你真的需要这个吗?如果是这样,您可以按名称将其存储在字典中,也可以将所有VCs存储在
NSMutableSet
中。但在大多数情况下,您确实不需要它,因为大多数UI控制器(如NavController)将为您管理内存

另一种动态性较差的方法是在开始时创建所有视图控件并将它们放入字典中,然后您可以根据发送方将它们从字典中加载。这具有更好的编译时检查的优点,但会占用更多内存