概述:
首先,我UITableView
使用Interface Builder将其置于Xcode生成的视图中.视图的文件所有者设置为Xcode生成的子类UIViewController
.为了这个子类我已经加入工作的实施numberOfSectionsInTableView: tableView:numberOfRowsInSection:
以及tableView:cellForRowAtIndexPath:
与表视图的dataSource
,并delegate
通过在Interface Builder文件所有者连接到这个类.
上述配置没有问题.当我想将这个Table View dataSource
和delegate
-implementations移到一个单独的类时,问题就出现了,很可能是因为除了Table View之外还有View上的其他控件,我想将Table View相关的代码移到它的自己的班级.为此,我尝试以下方法:
UITableViewController
在Xcode中创建一个新的子类
移动已知良好的实现numberOfSectionsInTableView:
,tableView:numberOfRowsInSection:
并移动tableView:cellForRowAtIndexPath:
到新的子类
将a 拖到InterfaceBuilder中现有 XIB UITableViewController
的顶层 ,删除为此自动创建的/ ,然后将该类设置为与新子类匹配UIView
UITableView
UITableViewController
UITableViewController
删除以前工作UITableView
的现有dataSource
和delegate
连接,并将它们连接到新的UITableViewController
完成后,我没有工作UITableView
.我最终得出了三个结果中的一个,这些结果似乎随机发生:
当UITableView
加载时,我得到一个运行时错误,指示我发送tableView:cellForRowAtIndexPath:
到一个无法识别它的对象
当UITableView
加载时,项目会毫无错误地进入调试器
没有错误,但UITableView
没有出现
通过一些调试并创建了一个基本项目来重现这个问题,我通常会看到上面的第三个选项(没有错误但没有可见的表视图).我添加了一些NSLog调用,发现虽然numberOfSectionsInTableView:
并且numberOfRowsInSection:
都被调用,但cellForRowAtIndexPath:
不是.我确信我错过了一些非常简单的事情,希望对于经验丰富的人来说答案可能是显而易见的.如果这不是一个简单的答案,我很乐意更新一些代码或示例项目.谢谢你的时间!
完成重现的完整步骤:
在Xcode中创建一个新的iPhone OS,基于视图的应用程序并调用它 TableTest
TableTestViewController.xib
在Interface Builder中打开并将其拖动UITableView
到提供的视图表面上.
将UITableView
's dataSource
和delegate
-outlets 连接到File的Owner,它应该已经代表TableTestViewController
-class.保存更改
回到Xcode,添加以下代码 TableTestViewController.m:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { NSLog(@"Returning num sections"); return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSLog(@"Returning num rows"); return 1; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"Trying to return cell"); static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } cell.text = @"Hello"; NSLog(@"Returning cell"); return cell; }
Build and Go,你应该看到单词Hello
出现在UITableView
现在尝试将这个UITableView
逻辑移到一个单独的类中,首先在Xcode中创建一个新文件,选择UITableViewController
子类并调用该类TableTestTableViewController
从上面删除上面的代码片段TableTestViewController.m
并将其放入TableTestTableViewController.m
,用我们的方法替换这三种方法的默认实现.
返回同一TableTestViewController.xib
文件中的Interface Builder ,将a UITableViewController
拖入主IB窗口并删除UITableView
自动附带的新对象
将此new的类设置UITableViewController
为TableTestTableViewController
从以前工作的现有的绑定中删除dataSource
和delegate
绑定,UITableView
并将相同的两个绑定重新连接到TableTestTableViewController
我们创建的新绑定.
保存更改,构建和继续,如果您得到我得到的结果,请注意UITableView
不再正常运行
解决方案:
通过iPhone开发人员论坛的更多故障排除和一些帮助,我已经记录了一个解决方案!UIViewController
项目的主要子类需要一个指向UITableViewController
实例的出口.要完成此操作,只需将以下内容添加到主视图的标题(TableTestViewController.h
)中:
#import "TableTestTableViewController.h"
和
IBOutlet TableTestTableViewController *myTableViewController;
然后,在Interface Builder中,将文件所有者的新插座连接到TableTestTableViewController
主IB窗口.XIB的UI部分不需要进行任何更改.只需将此插座安装到位,即使没有用户代码直接使用它,也可以完全解决问题.感谢那些在iPhone开发人员论坛上为BaldEagle提供帮助和信誉的人,以寻找解决方案.
我按照你的步骤重新创建了项目并遇到了同样的问题.基本上你几乎就在那里.丢失了2件事(一旦修复就有效):
您需要将连接tableView
的TableTestTableViewController
到UITableView
你的屏幕上.正如我之前所说,因为它不是IBOutlet
你可以覆盖tableView
属性并使它和IBOutlet
:
@interface TableTestTableViewController : UITableViewController { UITableView *tableView; } @property (nonatomic, retain) IBOutlet UITableView *tableView;
接下来就是添加TableTestTableViewController
对它的引用并将其保留在TableTestViewController
.否则你TableTestTableViewController
可能会被释放(在加载笔尖后没有任何东西悬挂在它上面.)这就是为什么你看到不稳定的结果,崩溃或什么都没有显示.为此,请添加:
@interface TableTestViewController : UIViewController { TableTestTableViewController *tableViewController; } @property (nonatomic, retain) IBOutlet TableTestTableViewController *tableViewController;
并将Interface Builder中的TableTestTableViewController
实例连接到实例.
有了上述,这在我的机器上运行良好.
此外,我认为说明所有这些背后的动机(而不仅仅是使用UITableViewController
自己的动力)会很好UITableView
.在我的情况下,它是使用其他视图,只是UITableView
在同一屏幕的内容.所以我可以添加其他UILabels
或UIImages
下面UIView
并显示UITableView
在他们下面或上面.
我只花了很多时间拉着我的头发试图弄清楚UITableView
当我将它嵌入一个单独的笔尖而不是主笔尖时为什么不会出现.我终于在上面找到了你的讨论,并意识到这是因为我UITableViewController
没有被保留!显然,委托和数据源属性UITableView
没有标记为"保留",所以我的笔尖正在加载,但是控制器被抛出了......由于objective-c的奇迹,我没有得到任何错误消息......我仍然不明白为什么它没有崩溃.我知道我之前看过"发送给发布的xxx的消息"......为什么不给它一个呢?!?
我认为大多数开发人员会认为他们在界面构建器中构建的结构将保存在一些更大的上下文(Nib)中,而不会被释放.我想我知道他们为什么这样做..所以iPhone可以在低内存中丢弃并重新加载部分笔尖.但男人,这很难搞清楚.
有人可以告诉我应该在文档中阅读有关该行为的内容吗?
另外 - 关于挂钩视图.首先,如果从UI构建器中拖入一个,您将看到它们将视图属性(这是一个IBOutlet
)连接到表视图.没有必要公开tableView
,似乎在内部设置.事实上,除非您想要viewDidLoad
通知,否则似乎没有必要设置视图.我刚刚打破了我uitableview
和uitableviewcontroller
(只有委托和数据源集)之间的视图连接,它显然工作正常.