【问题标题】:Objective-C: elegant solution to conditional creation of objects?Objective-C:有条件地创建对象的优雅解决方案?
【发布时间】:2009-10-02 13:49:47
【问题描述】:

这是一个 Objective-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];
}

我可以为每个按钮复制此代码并更改相应的类(视图控制器类)),但我希望有一个更优雅的解决方案。

有人知道怎么做吗?

【问题讨论】:

    标签: objective-c iphone


    【解决方案1】:

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

    - (MoreViewController *)init
    {
        self = [super initWithNibName:@"MoreView" bundle:nil];
        if (self != nil)
        {
        }
        return self;
    }
    

    这将使您的视图控制器自包含,以便您可以干净地创建它们:

    MoreViewController *moreViewController = [[MoreViewController alloc] init];
    

    无论您做什么,我都推荐这种方法。 Apple 的示例代码无法承受,将 NIB 的名称放在调用者中是愚蠢的。为什么每个视图控制器的调用者都需要知道这个内部实现细节?

    接下来,请记住 ObjC 是一种动态语言。您可以像这样根据它们的类 name 构造对象:

    Class vcClass = NSClassFromString([self.classNameForSender objectForKey:sender])
    UIViewController *vc = [[[vcClass alloc] init] autorelease];
    [self switchToView:vc];
    

    在上面,-classNameForSender 是一个将按钮对象映射到类名的NSDictionary,但是您当然可以通过许多其他方式获得这些类名。根据发件人的不同,您可以将课程直接挂在发件人上(尽管这对于标准 UIControls 来说很困难,因为它们只有一个整数 tag 可以使用)。

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

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

    【讨论】:

      【解决方案2】:

      一个简单的改进是在每个按钮创建时设置标签属性

      - (IBAction)som​​eButtonPressed:(id)sender{ // 在这里切换视图 开关(sender.tag){ 案例0: 如果(self._moreViewController == nil){ MoreViewController *moreViewController = [[MoreViewController alloc] initWithNibName:@"MoreView" bundle:[NSBundle mainBundle]]; self._moreViewController = moreViewController; [更多ViewController 发布];} [self SwitchView:self._moreViewController]; 休息; 情况1: 如果(self._lessViewController == nil){ MoreViewController *lessViewController = [[LessViewController alloc] initWithNibName:@"LessView" bundle:[NSBundle mainBundle]]; self._lessViewController = 少视图控制器; [lessViewController 发布];} [self SwitchView:self._lessViewController]; 休息; } }

      那样你只有一个功能。但是,最好不要在 case 语句中重复代码,而只需提供要实例化的类的参数。这不是我尝试过的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 2018-04-28
        • 1970-01-01
        • 2015-07-03
        • 2011-03-31
        • 2011-02-13
        • 1970-01-01
        相关资源
        最近更新 更多