【问题标题】:Weird behavior of UITableView data source methodsUITableView 数据源方法的奇怪行为
【发布时间】:2013-12-06 18:12:21
【问题描述】:

我想创建一个具有标准 tableview 数据源方法(-cellForRowAtIndexPath:-numberOfRows 等)的默认实现的 UIViewController 类。

我想创建一个自定义下拉列表。

这是我的问题的详细说明:
我定义了MyDropDownListController 类,它实现了UITableViewDelegateUITableViewDataSource 协议,其中UITableView ivar 称为table

然后,我定义一个自定义的配置方法:

-(void)initDropDownListWithItems:(NSArray*)items andAddToView:(UIView*)view
{
    dropDownItems = items; //data source array of items to display in list
    table = [[UITableView alloc] initWithFrame: CGRectMake(view.frame.origin.x, view.frame.origin.y + view.frame.size.height + 1, view.frame.size.width, 140)];
    [view addSubview:table]; //add my table to view
    [table setDataSource:self];
    [table setDelegate:self];
    [table reloadData];
 }

然后我定义-numberOfRowsInSection:cellForRowAtIndexPath
在此之后,在其他一些 UIViewController 类中(我想要我的下拉列表)我有这个:

dataSource = @[@"first", @"second", @"third"];
MyDropDownListController * list= [[MyDropDownListController alloc] init];
[list initDropDownListWithItems:dataSource andAddToView:someViewInThisController];

启动应用程序后,显示此列表时出现奇怪的异常,例如:

-[_UIParallaxDimmingView tableView:numberOfRowsInSection:]:无法识别的选择器发送到实例 0x16500c70

如您所见,MyDropDownListController 并没有调用数据源方法,而是为其他一些奇怪的事情调用了数据源方法。

这些消息可能会有些不同:

[UIBarButtonItem tableView:numberOfRowsInSection:]: 无法识别 发送选择器

等等。

希望您能看到问题所在。
正如我在这里所说的那样,MyDropDownListController 似乎没有调用数据源方法:

[table setDataSource:self];

但对于其他一些东西。

【问题讨论】:

  • 您能否在代码中的某个位置再次设置表的数据源?是否在MyDropDownListController 中实现了所需的数据源方法?
  • @BlackRider 不,我只是在这个initDropDown 方法中第一次设置它们。是的,我说过Then I define numberOfRowsInSection: and cellForRowAtIndexPath and etc.
  • 很奇怪。 [table reloadData] 内部的 initDropDownListWithItems 调用是否成功?
  • @BlackRider 这个问题即使我不​​打电话[table reloadData]
  • @BlackRider 我从帖子中删除了这个电话,以免误导。正如我所理解的那样,这些方法中的自我问题?因为代替它的方法接收者是一些其他未知对象

标签: ios objective-c cocoa-touch uitableview ios7


【解决方案1】:

我的猜测是,将表作为类变量的视图控制器正在被释放,因为它的引用计数在函数末尾为 0。当您执行以下操作时:

{
dataSource = @[@"first", @"second", @"third"];
MyDropDownListController * list= [[MyDropDownListController alloc] init];
[list initDropDownListWithItems:dataSource andAddToView:someViewInThisController];
}

在函数 ARC 结束时,如果内存不再被任何东西引用,则将其标记为可重用。您将控制器引用为 tableview 的委托,但委托是弱引用,不计入 ARC。所以你得到无法识别的选择器的原因是因为ARC标记了内存位置以供重用,然后操作系统通过在那里放置新对象来重用它。然后您的表将其称为委托(由于操作系统重新填充内存,它仍然是一个有效对象)并且您收到一个无法识别的选择器错误。如果您在发生这种情况时没有创建对象,那么您将收到bad access 错误,该错误可以通过 NSZombies 进行跟踪。

【讨论】:

  • 谢谢。但我不明白你的意思是什么:“类变量”?在 Objective-C 中,我只知道类方法。可能你的意思是局部变量?
  • @interface 中定义的变量(无论是属性还是iVar)都是类变量(至少在我的命名法中)。在函数(方法)中定义的任何东西都是局部变量(局部意味着它将在函数结束时消失)。
猜你喜欢
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多