General Description:

首先,我有一个UITableView,它已被放置到使用Interface Builder生成的Xcode视图中.视图的文件所有者设置为Xcode生成的UIViewController子类.在这个子类中,我添加了numberOfSectionsInTableView: tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath:的工作实现,表视图的dataSourcedelegate通过Interface Builder中的文件所有者连接到这个类.

以上配置工作正常.当我想将这个表视图的dataSourcedelegate实现移出到一个单独的类中时,就会出现这个问题,很可能是因为除了表视图之外,视图上还有其他控件,我想将与表视图相关的代码移出到它自己的类中.为了实现这一点,我try 以下方法:

  • 在Xcode中创建一个UITableViewController的新子类
  • Move the known-good implementations of numberOfSectionsInTableView:, tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath: to the new subclass
  • UITableViewController拖动到InterfaceBuilder中existing XIB的顶层,删除为该UITableViewController自动创建的UIView/UITableView,然后将UITableViewController的类设置为与新子类匹配
  • Remove the previously-working UITableView's existing dataSourcedelegate connections 和 connect them to the new UITableViewController

完成后,我没有一个工作UITableView.我最终得到了三种结果中的一种,这三种结果似乎是随机发生的:

  • 加载UITableView后,我会收到一个运行时错误,表明我正在向一个无法识别它的对象发送tableView:cellForRowAtIndexPath:
  • 在没有错误的情况下加载到调试器时
  • 没有错误,但UITableView没有出现

经过一些调试,并创建了一个基本项目来重现这个问题,我通常会看到上面的第三个选项(没有错误,但没有可见的表视图).我添加了一些NSLog调用,发现虽然numberOfSectionsInTableView:numberOfRowsInSection:都被调用,但cellForRowAtIndexPath:没有.我确信我错过了一些非常简单的事情,并希望答案对比我更有经验的人来说可能是显而易见的.如果这不是一个简单的答案,我很乐意用一些代码或示例项目进行更新.谢谢你抽出时间!

Complete steps to reproduce:

  • Create a new iPhone OS, View-Based Application in Xcode 和 call it TableTest
  • Open TableTestViewController.xib in Interface Builder 和 drag a UITableView onto the provided view surface.
  • Connect the UITableView's dataSourcedelegate-outlets to File's Owner, which should already represent the TableTestViewController-class. Save your changes
  • 回到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;
}
  • 构建并运行,你会看到单词Hello出现在UITableView

  • 现在,为了try 将UITableView的逻辑转移到一个单独的类中,首先在Xcode中创建一个新文件, Select UITableViewController子类并调用TableTestTableViewController

  • Remove the above code snippet from TableTestViewController.m 和 place it into TableTestTableViewController.m, replacing the default implementation of these three methods with ours.
  • Back in Interface Builder within the same TableTestViewController.xib-file, drag a UITableViewController into the main IB window 和 delete the new UITableView object that automatically came with it
  • 将这个新的UITableViewController级设置为TableTestTableViewController
  • Remove the dataSourcedelegate bindings from the existing, previously-working UITableView 和 reconnect the same two bindings to the new TableTestTableViewController we created.
  • Save changes, Build 和 Go, 和 if you're getting the results I'm getting, note the UITableView no longer functions properly

Solution:

#import "TableTestTableViewController.h"

IBOutlet TableTestTableViewController *myTableViewController;

Then, in Interface Builder, connect the new outlet from File's Owner to TableTestTableViewController in the main IB window. No changes are necessary in the UI part of the XIB. Simply having this outlet in place, even though no user code directly uses it, resolves the problem completely. Thanks to those who've helped 和 credit goes to BaldEagle on the iPhone Developer Forums for finding the solution.

推荐答案

我遵循了你的步骤,重新创建了项目,遇到了同样的问题.基本上你就快到了.缺少两件事(一旦修复,它就会工作):

  • 您需要将TableTestTableViewController中的tableView连接到屏幕上的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.所以我可以在UIView下面加上UILabelsUIImages,然后在它们下面或上面显示UITableView.

Objective-c相关问答推荐

Objective-C:为什么[对象复制]的两个请求返回相同的结果?

Objective C 中的 RSA 实现

iOS9 - 这个应用程序正在从后台线程修改自动布局引擎 - 在哪里?

如何打印 NSMutableURLRequest?

获取 Objective-C 类或实例的所有方法

何时使用静态字符串与 #define

NSManagedObjectContext performBlockAndWait:不在后台线程上执行?

NSString:从字符串中删除 UTF-8 重音的简单方法?

iOS:使用设备修饰符加载 xib 文件?

UILabel 的角半径属性在 iOS 7.1 中不起作用

对块进行类型定义是如何工作的

Lipo错误!!无法打开输入文件

iOS6:supportedInterfaceOrientations 不起作用(被调用但界面仍然旋转)

为什么 NSOrderedSet 不继承自 NSSet?

检测 iOS 应用程序是否在调试器中运行

Xcode:无法判断应用程序包

导航返回时重新加载 UITableView?

NSMutableArray addObject 不起作用

NSString 中子字符串的出现次数?

Facebook SDK 登录永远不会在 iOS 9 上回调我的应用程序