从TableView管理多个ViewControllers

时间:2011-06-28 01:11:35

标签: iphone uitableview uiviewcontroller

我很好奇是否有人有从TableView管理多个ViewControllers的想法。我有一个大约七个项目的列表,我在TableView中显示,每个项目都有一个ViewController。我的第一个想法是用各种ViewControllers初始化一个数组。

NSMutableArray *viewControllers = [[NSMutableArray alloc] initWithCapacity:7];
[viewControllers addObject:[[ViewController1 alloc] initWithNibName:@"View1" bundle:nil]];
[viewControllers addObject:[[ViewController2 alloc] initWithNibName:@"View2" bundle:nil]];
...

然后引用该数组以加载项目选择的相应视图。

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [self.navigationController pushViewController:[viewControllers objectAtIndex:indexPath.row] animated:YES];
}

我真的不确定这是否合适。任何方向都会很棒。

编辑:

根据Ryan和Joe的反馈,我实现了一个对象来保存我的表项。缩小我的问题也导致了对实现细节的一些混淆。添加了完整的解决方案来管理视图控制器和选择标签栏项目。

TableNavigationItem.h

#import 


@interface TableNavigationItem : NSObject {
    NSString *title;
    NSNumber *tabIndex;
    id viewController;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSNumber *tabIndex;
@property (nonatomic, retain) id viewController;

@end

TableNavigationItem.m

#import "TableNavigationItem.h"


@implementation TableNavigationItem

@synthesize title;
@synthesize viewController;

- (id) init{

    if(self = [super init]){
        self.title = @"";
    }

    return self;
}

- (void) dealloc {
    [title release];
    [tabIndex release];
    [viewController release];
    [super dealloc];
}

@end

然后按Joe的建议初始化。

NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:7];
TableNavigationItem *navItem;

// view 1
navItem = [[TableNavigationItem alloc] init];
navItem.title = @"View 1";
navItem.tabIndex = [NSNumber numberWithInt:1];
[mutableArray addObject:navItem];
[navItem release];

// view 2
navItem = [[TableNavigationItem alloc] init];
navItem.title = @"View 2";
navItem.viewController = [ViewController2 class]];
[mutableArray addObject:navItem];
[navItem release];

...

// store the navigation items
self.tableItems = [NSArray arrayWithArray:mutableArray];
[mutableArray release];

然后

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    TableNavigationItem *navItem = [tableItems objectAtIndex:indexPath.row];
    if(navItem.viewController != nil){
        [self.navigationController pushViewController:[[[navItem.viewController alloc] init] autorelease] animated:YES];
    }
    else if(navItem.tabIndex != nil){
        [((MyAppDelegate *)[UIApplication sharedApplication].delegate).tabBarController setSelectedIndex:[navItem.tabIndex integerValue]];
    }
}

2 个答案:

答案 0 :(得分:1)

这听起来不错。我唯一担心的是你的视图控制器是否是RAM重的,在这种情况下你可能想做出决定:是否更好地预先分配所有内容(即你确定你可以将所有这些控制器的状态放在可用内存中?)或者根据需要采用延迟命中加载适当的视图控制器是否更好?

看起来您的ViewControllers属于不同的类。如果是这种情况(并且如果每个人总是使用相同的nib),我会考虑在每个nib上实现自定义-init方法,并使您的选择数组成为Class个对象之一。不过,这只是个人偏好的问题。

还有一件事:你会想要自动释放那些视图控制器,否则无论如何都会泄漏内存。

答案 1 :(得分:1)

如果控制器管理的所有视图都立即显示在屏幕上,那么这种方法没有任何问题。确保在-viewDidUnload中释放VC的数组,并在-viewDidLoad中重新创建它,这样运行时可以在屏幕上按下下一个视图时卸载所有这些额外的对象。请注意,只有根视图控制器才会收到视图生命周期事件;您创建的视图控制器和手动将拥有的视图添加到表中将不会获得这些调用的方法。您必须实现一些管道,通过通知或委派将这些视图生命周期事件放入“子视图”。

您问题的最佳答案是“仪器化”。至少运行Allocations和VM仪器,并检查这些视图控制器消耗的内存量。如果您希望通过仪器提高您的技能,请观看WWDC 2011的性能会话,他们在教授如何使用它来查找内存和性能问题方面做得很好。