前言:我是iPhone SDK,Obj-C,Interface Builder和Cocoa的新手。我可能做了一些明显不对的事。
问题:
我有一个UITableView
,如果我滚动它会崩溃。它将滚动一点以显示最底部半隐藏单元格的完整单元格,但不会加载下一个单元格。同样,如果我滚过顶部以完全隐藏最底部的单元格,并且橡皮筋向后显示该单元格,它将在显示之前崩溃。这让我感到奇怪,因为它正确地绘制了11个单元格中的前7个单元格。单元格数据位于NSArray
中,UITableViewController
链接为Interface Builder中dataSource
的{{1}}和delegate
。它在视图初始化时有效。
我正在制作一个应用程序我认为我将在2天前完成,只计算组合并在我认为方便的滚动表视图中显示它们的列表。现在,它甚至没有计算所有内容,UITableView
中的NSArray
使用DataSource
和@"Hello"
之类的字符串初始化一次。
重现的步骤: 因为我正在使用IB,所以我无法在代码中向您展示完整的故事。所以我要描述我到目前为止所做的事情,并希望它不会让你昏昏欲睡。
在Xcode中制作了一个新的“Tab Bar Application”,因为我想要2个标签,而且我不想要导航栏或全屏幕表。我将@"World"
的第一个标签视图移至MainWindow.xib
,作为给定FirstView.xib
的模拟。这很好用。我修改了视图以包含两个用于输入的SecondView.xib
和一个用于输出的UITextField
。这很有效,但桌子是空的。我将UITableView
子类化,其中我填充了一个名为UITableViewController
的{{1}}属性,其中包含11个字符串,然后添加了
NSArray
只有评论。在IB中,我向combinations
添加了// Set up the cell...
cell.userInteractionEnabled = NO;
cell.text = [combinations objectAtIndex:indexPath.row];
并设置了它的类名以匹配此新子类的名称,并将我视图中的Table View Controller
控制拖动到此FirstView.xib
两次。链接Table View
和Combinations Table View Controller
后。如果只链接dataSource
,我会得到相同的行为。
这将使用delegate
dataSource
中的前7个值运行并填充表格的可见行(6.5)。我可以向下滚动0.5个单元格,然后再向上滚动。但如果我向上或向下滚动超过0.5个单元格,应用程序将崩溃。报告中的解释如下:
dataSource
我没有制作combinations
,也没有将其链接到我的*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSCFTimer tableView:cellForRowAtIndexPath:]:
unrecognized selector sent to instance 0x52ca40'
,我怀疑NSCFTimer
正好是应该转到Table View
的消息}或cellForRowAtIndexPath
所以我很困惑为什么它误入歧途以及它最终走向何方。
更新:感谢您的回答和评论。我的问题似乎是dataSource
(delegate
的子类)实际上没有在我的代码中的任何特定位置实例化。它确实被创建为一段时间(加载CombinationsTableViewController
时)并且在初始tableView充满7个单元格时显然被管理,然后被释放。所以我需要确定在何处/如何对此控制器进行保留引用。我的UITableViewController
应该有一些插座可以保存这个控制器,可以将其链接为FirstView.xib
中的实例。是的,我是新手。我知道我可以通过避免IB并在代码中明确地做事来消除这些麻烦,但我想我想学会灵活地使用IB。
最后:是的,我需要一个保留的表视图控制器实例。这听起来很简单,但是当我和IB一起工作时,这一点并不清楚。阅读我自己的帖子了解整个过程并修复。
除了:调试器需要详细的说明(任何链接赞赏),或者它不能很好地工作。通过让App崩溃并阅读它生成的报告,我似乎可以更快地获得更多信息。但这需要一个乏味的终止,重新启动和3次点击。我真的想继续从这里开始连接输入,进行计算,并在每次更改时更新表格。这应该是困难的部分,而不是让框架成员工作的东西。
进一步漫无边际:这完全出现在iPhone SDK for 2.2.1中。当时没有加入俱乐部以获得冷硬现金的iPhone OS 3.0非测试版尚未推出。我预计它将在WWDC 2009开放,但实际上今天(2009年7月17日)已经提供了免费的公共3.0 SDK。
答案 0 :(得分:7)
看起来你正在丢失你的tableView委托。
看起来正在发生的事情是UITableViewDelegate正在发布,然后应用程序使用相同的指针地址为NSCFTimer。
你有没有在你的delegete上调用release,或者如果它在自动释放池中你没有保留该委托。
答案 1 :(得分:5)
好的,如果您按照步骤重现,我现在将添加解决此问题的步骤:
解决此问题的步骤
子类UIViewController
。我打电话给我CombinationsViewController
。在此控制器中,从下面的第6步为combinations
Table
ViewController
添加一个属性作为IBOutlet。
不要忘记导入正确的东西,并合成表视图控制器,也可以用dealloc
方法释放它。
在FirstView.xib
中将File's Owner
类更改为此最新的子类。
将它的combinationViewController插座链接到下面第7步中Combinations Table View Controller
中的FirstView.xib
。
打开TabBarController
中的MainWindow.xib
选择第一个标签,然后在Identity Inspector中将类更改为最新的子类(CombinationsViewController
)。
这使得表格正常填充并滚动内容。
现在我要继续前进并获得一些自定义表视图单元格的东西,并实际让我的应用程序做的事情。
枚举重现的步骤作为修复的参考:
在Xcode中制作了一个新的“标签栏应用程序”。
打开Tab View Controller
,将第一个标签的预制视图拖到MainWindow.xib
制作一个名为FirstView.xib
的xib新视图作为给定SecondView.xib
的模拟,并将该预制视图放入此xib。
将视图关联到File's Owner
的{{1}}商店。
我修改了视图以包含两个用于输入的view
和一个用于输出的UITextField
。
我将UITableView
子类化为UITableViewController
,其中我填充了一个名为CombinationsTableView
的{{1}}属性,其中包含11个字符串,然后添加了NSArray
代码那里只有关于设置单元格的评论。
在combinations
中,我添加了cell.text = [combinations objectAtIndex:indexPath.row];
并设置了它的类名以匹配此新子类的名称,并将我视图中的FirstView.xib
控制拖到此{ {1}}两次。关联Table View Controller
和Table View
。
此时表格会使用数据进行渲染,但滚动会中断。这是因为CombinationsTableView不会保留在任何位置。对于第一次IB用户来说,这是非常不清楚的。所以你需要应用上面列出的修复。
第一个在答案中总结这一点的人会得到正确的答案复选标记。例如。创建一个viewController子类,它是FirstView.xib的文件所有者,并包含一个保留的IBOutlet,您可以在同一个xib文件中链接到表视图控制器。
答案 2 :(得分:4)
第一个单元格加载的原因是因为tableview预加载了与屏幕上其他单元格类似的内容。
所有单元格都是从数据源方法加载的:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
我确保你明确地设置了tableView的委托和数据源。这可以在代码或IB中完成。由:
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
同样正如Bluephlame所说,你可能会在某处释放UITableVewController。
要找到答案,请在dealloc方法中设置断点:
- (void)dealloc{
//releasing things
[super dealloc];
}
如果你确实发布它,你将会遇到这个断点。然后你就可以开始追查罪魁祸首了。
答案 3 :(得分:2)
我遇到了同样的问题,并通过在数组中添加nil作为最后一项来修复它。
这是崩溃:
pairs = [[NSArray alloc] initWithObjects:@"EUR/USD",@"USD/JPY",@"GBP/USD",@"USD/CHF",@"USD/CAD"];
但不是这样:
pairs = [[NSArray alloc] initWithObjects:@"EUR/USD",@"USD/JPY",@"GBP/USD",@"USD/CHF",@"USD/CAD",nil];
希望这有帮助。
答案 4 :(得分:2)
将内存分配给数组而不是[NSArray arrayWithObjects:];
。没有内存分配,它不会重新加载行....使用array=[NSArray alloc] initWithObjects];
...而不是上面的。
答案 5 :(得分:0)
我有同样的问题。我在一个nib文件中有一个UITableViewController子类,但我只声明 UITableView 作为一个outlet / property,tableview的 UITableViewController 在使用时被释放了
快速修复只是向引用嵌入式UITableViewController的File的Owner类添加一个插座。