表视图数据源运行两次,范围问题

时间:2011-05-01 02:37:36

标签: iphone objective-c uitableview scope

我有一个UITableView,其中numberOfSectionsInTableView和numberOfRowsInSection被调用两次,第二次运行时会出现范围问题。如果我掩盖了问题,我会在第一次运行cellForRowAtIndexPath时遇到范围问题。

大多数数据都来自在viewDidLoad期间配置的NSDictionary。我也同时配置了NSArray。一旦设定,它们永远不会被改变或释放。

第一次调用numberOfSectionsInTableView时,没关系。根据需要计算元素等。然后立即调用第二次(不知道为什么)。在第二次运行时,它无法访问NSDictionary或NSArray项。即使在尝试NSLog时也会崩溃。例如:

NSLog(@"theMainDictionary %@",theMainDictionary);

通常会产生EXC_BAD_ADDRESS但偶尔也会出现这样的情况:

theMainDictionary <_UITableViewSeparatorView: 0x4e73680; frame = (0 307; 320 1); opaque = NO; autoresize = W; layer = <CALayer: 0x4e4bf20>>

同样,第一次运行时,同一行运行良好(按预期记录字典)。

如果我通过返回一个固定的NSInteger来掩盖问题,那么numberOfRowsInSection会做同样的事情。如果我屏蔽numberOfRowsInSection,则cellForRowAtIndexPath在第一次运行时崩溃。同样的问题 - 无法访问主菜词或相关的NSArray。

我无法弄清楚为什么它们会运行两次 - 在任何地方都没有reloadData。我也不知道为什么第二次通话以不同的方式运行。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您可能正在使用[NSDictionary dictionary]或其中一种类似的工厂方法(返回自动释放的实例)创建字典,然后将其直接保存到ivar而不保留它。它将正常工作,直到您的程序返回主运行循环,此时自动释放将解析并释放对象。

有几种方法可以解决它:

  • 分配给声明为retain的属性而不是ivar。这意味着self.theMainDictionary而不仅仅是theMainDictionary。这将保留给您,因此它会一直存在,直到您释放它(或为该属性分配不同的字典或nil)。
  • 使用[[NSDictionary alloc] init](或许多其他init方法之一)而不是[NSDictionary dictionary]样式。这将返回您拥有的实例,因此它会一直存在,直到您释放它为止。
  • 将字典保存到ivar时,在字典上显式调用retain。这需要所有权,所以它会一直存在,直到你发布它。

在所有情况下,请记住在dealloc方法中发布字典,否则内存将泄漏。

以上所有内容也可能适用于阵列。有关Cocoa中内存管理的更详细说明,请参阅Apple's documentation