代码之家  ›  专栏  ›  技术社区  ›  dlamblin

uiTableView滚动崩溃应用程序

  •  11
  • dlamblin  · 技术社区  · 15 年前

    序言 :我是iPhone SDK、OBJ-C、Interface Builder和Cocoa的新手。我可能做了一些明显错误的事情。

    问题 : 我有一个 UITableView 如果我滚动它就会崩溃。它将滚动一点以显示最下面半个隐藏单元格的完整单元格,但不会加载下一个单元格。类似地,如果我滚动到顶部完全隐藏最底部的单元格,并且它用橡皮筋向后显示该单元格,那么在显示该单元格之前,它将崩溃。这让我觉得很奇怪,因为它正确地绘制了11个单元格中的前7个。单元格数据位于 NSArray ,在 UITableViewController 链接为 dataSource delegate 对于 UITababVIEW 在接口生成器中。它在视图初始化时工作。

    我正在制作一个应用程序,我认为我已经完成了2天前,只是计算组合,并显示它们的列表,在我认为是一个方便的滚动表视图。现在,它甚至不计算所有的东西, 不可变数组 DataSource 用类似这样的字符串初始化一次 @"Hello" @"World" .

    复制的步骤 : 因为我使用的是ib,所以我不能用代码准确地向您展示整个故事。所以我要描述一下我到目前为止所做的,希望它不会让你昏昏欲睡。

    在Xcode中创建了一个新的“标签栏应用程序”,因为我需要两个标签,我不需要导航栏,也不需要全屏表格。我感动了 MainWindow.xib 的第一个选项卡视图 FirstView.xib 类似于给定的 SecondView.xib . 这很管用。我将视图修改为包含两个 UITextField S代表输入,A UITababVIEW 用于输出。这行得通,但桌子是空的。我将 表格控制器 在那里我填充了一个 不可变数组 属性命名 combinations 有11个字符串,然后添加

    // Set up the cell...
    cell.userInteractionEnabled = NO;
    cell.text = [combinations objectAtIndex:indexPath.row];
    

    只有评论。在IB中我添加了一个 Table View Controller 第一视角 并将其类名设置为与新子类的名称匹配,然后控件拖动 Table View 在我看来这个 Combinations Table View Controller 两次。一旦链接到 数据源 一次 代表 . 尽管我也有同样的行为 数据源 是联系在一起的。

    这将运行并使用表中的前7个值填充表的可见行(6.5)。 数据源 组合 . 我 可以 向下滚动0.5个单元格,然后向上滚动。但是如果我上下滚动超过0.5个单元格,应用程序就会崩溃。报告中的解释是:

    *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
    reason: '*** -[NSCFTimer tableView:cellForRowAtIndexPath:]:
    unrecognized selector sent to instance 0x52ca40'
    

    我没做过 NSCFTimer 我也没有把它和我的 表格视图 ,我怀疑 cellForRowAtIndexPath 是一个应该传达给我的信息 数据源 代表 所以我对它为什么会误入歧途以及最终会走向何处感到困惑。

    更新 :感谢您的回答和评论。我的问题似乎是 CombinationsTableViewController (子类) 表格控制器 )在我的代码中没有实例化任何特定的地方。它确实被创建为一段时间(当 第一视角 被加载),并且在初始TableView被7个单元格填充时被明显地管理,然后被释放。因此,我需要确定在哪里/如何对这个控制器进行保留的引用。我的 Application Delegate 可能应该有一个插座来容纳这个控制器,该控制器可以作为实例链接,该实例位于 xib .是的,我是新来的。我知道我可以通过避免ib和在代码中显式地做一些事情来消除这些麻烦,但是我想学会灵活地使用ib。

    终于 :是的,我需要表视图控制器的保留实例。这听起来很简单,但这在我和IB合作时并不清楚。在整个过程中阅读我自己的帖子并修复。

    旁白 :要么调试程序需要详细的指令(需要任何链接),要么它不能很好地工作。我似乎通过让应用崩溃并阅读它生成的报告来更快地获得更多信息。但这需要一个冗长的终止、重新启动和3次点击。我真的很想从这个开始,连接输入,进行计算,并用每次更改更新表。这应该是最困难的部分,而不是让框架成员工作的部分。

    进一步杂乱无章 :这都在iPhone 2.2.1版的SDK中。当时,iPhoneOS3.0的非测试版还没有上市,就没有加入俱乐部,获得硬现金。我原以为它会在WWDC 2009年的公开赛上,但实际上是在今天(2009年7月17日),免费的public 3.0sdk才上市。

    6 回复  |  直到 15 年前
        1
  •  7
  •   Nosredna    15 年前

    看起来您正在失去TableView代理。

    看起来正在发生的是,uiTableViewDelegate正在被释放,然后应用程序正在为nscftimer使用相同的指针地址。
    您是否在任何地方调用了delegee上的release,或者如果代理位于自动释放池中,您是否没有保留它。

        2
  •  5
  •   dlamblin    15 年前

    好吧,那么,如果你按照这些步骤进行复制,我现在将添加解决这个问题的步骤:

    解决此问题的步骤

    1. 子类A UIViewController . 我叫我的 CombinationsViewController . 在此控制器中,添加一个属性作为 combinations Table ViewController 从下面的步骤6开始。

    2. 不要忘记导入正确的内容,并合成表视图控制器,同时在 dealloc 方法。

    3. FirstView.xib 改变 File's Owner 类到这个最新的子类。

    4. 将它的CombinationsViewController出口链接到 Combinations Table View Controller 第一视角 在下面的步骤7中制作。

    5. 打开 TabBarController 在你 MainWindow.xib 选择第一个选项卡,并在标识检查器中将类更改为最新的子类。( 组合视图控制器 )

    这使得表可以正常填充并滚动内容。

    现在,我将继续进行最后一步,让一些定制的表格视图单元格的事情发生,实际上让我的应用程序做的事情。

    要复制的枚举步骤 作为对修复的参考:

    1. 在Xcode中创建了一个新的“标签栏应用程序”。

    2. 打开 Tab View Controller ,将第一个选项卡的预制视图拖到 主窗口

    3. 创建了一个新的基于视图的XIB 第一视角 类似于给定的 SecondView.xib 把这个预制的视图放到这个XIB中。

    4. 将视图链接到 文件所有者 view 出口。

    5. 我将视图修改为包含两个 UITextField S代表输入,A UITableView 用于输出。

    6. 我将 UITableViewController 作为 CombinationsTableView 在那里我填充了一个 NSArray 属性命名 组合 用11个字符串,然后添加 cell.text = [combinations objectAtIndex:indexPath.row]; 代码中只有关于设置单元格的注释。

    7. 第一视角 我添加了一个 Table View Controller 并将其类名设置为与新子类的名称匹配,然后控件拖动 Table View 在我看来这个 组合表视图控制器 两次。一旦链接到 dataSource 一次 delegate .

    此时,表确实会用数据呈现,但滚动会中断。这是因为CombinationsTableView不会保留在任何位置。对于第一次使用ib的用户来说,这是非常不清楚的。所以您需要应用上面列出的修复程序。

    第一个在答案中总结这一点的人会得到正确的答案复选标记。例如,创建一个view controller子类,它是firstview.xib的文件所有者,并且包含一个保留的iboutlet,您可以在同一个xib文件中链接到表视图控制器。

        3
  •  4
  •   Corey Floyd    15 年前

    第一个单元格加载的原因是,TableView预加载的内容与屏幕上的其他单元格一样。

    所有单元格都从数据源方法加载:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    

    我会确保您已经明确地设置了TableView的委托和数据源。这可以在代码或ib中完成。方法是:

    [self.tableView setDelegate:self];
    [self.tableView setDataSource:self];
    

    正如Bluephlam所说,您可能在某个地方释放了UITableVewController。

    要查找,请在dealoc方法内设置断点:

    - (void)dealloc{
    
    
         //releasing things
    
         [super dealloc];
    } 
    

    如果你释放它,你会碰到这个断点。然后你就可以开始追查罪犯了。

        4
  •  2
  •   Malcolm Box    13 年前

    将内存分配给数组而不是 [NSArray arrayWithObjects:]; . 如果没有内存分配,它将无法重新加载行….使用 array=[NSArray alloc] initWithObjects]; …而不是上面的。

        5
  •  2
  •   Cosmin    13 年前

    我有同样的问题,并通过将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];
    

    希望这有帮助。

        6
  •  0
  •   Lee    15 年前

    我也有同样的问题。我在NIB文件中有一个UITableViewController子类,但我只声明了 UITababVIEW 作为出口/财产,TableView的 表格控制器 在使用中被释放。

    快速修复方法只是向引用嵌入的UITableViewController的文件所有者类添加一个出口。