【问题标题】:reload table view : indexPath isn't reset ios 6重新加载表视图:indexPath 未重置 ios 6
【发布时间】:2013-07-30 17:19:17
【问题描述】:

我正在制作一个 iOS 6 程序,它从网站下载 JSON 数据并将其显示在表格视图中。我添加了一个拉动刷新方法,女巫工作正常。我可以进入设置视图控制器(secondViewController)并更改地址,一切正常。然后,我使用 pull to refresh 方法并重新加载了我的 tableView。但是如果我在更改地址后重新加载 3 次,我的应用程序就会崩溃。我收到此错误:

*** Terminating app due to uncaught exception 'NSRangeException', 
reason: '*** -[__NSArrayM objectAtIndex:]: index 10 beyond bounds for empty array'
*** First throw call stack:
(0x1ca1012 0x10dee7e 0x1c430b4 0x3084 0xdd8fb 0xdd9cf 0xc61bb 0xd6b4b 0x732dd 0x10f26b0   0x229dfc0 0x229233c 0x2292150 0x22100bc 0x2211227 0x22bb333 0x22bb75f 0x1c60376 0x1c5fe06 0x1c47a82 0x1c46f44 0x1c46e1b 0x1bfb7e3 0x1bfb668 0x22ffc 0x1fbd 0x1ee5)
libc++abi.dylib: terminate called throwing an exception

我做错了什么?我该如何解决这个问题?感谢您的帮助!

【问题讨论】:

  • 您的应用程序正在崩溃,因为您加载表格的数组是空的。您在哪里更改数组中的值?您需要添加更多 uitableview 委托的代码。
  • 你分配数组了吗?
  • 问题是我遵循了一个教程并且我使用了那个城市功能,所以我真的不知道如何处理它。我唯一做的是 City * currentCity = [citiesArray objectAtIndex:indexPath.row]; .

标签: iphone uitableview ios6 reload


【解决方案1】:

跳出的关键设计考虑因素是您的retreiveData 方法显然是异步更新模型(citiesArray),这意味着在此过程中与 tableview 的任何交互都可能失败。您永远不应该异步更新实际的citiesArray 本身。该数组的更新应该发生在主队列中。

您应该更改retrieveData 以不触及现有的citiesArray,而是创建并返回一个新数组,然后在您分派回主队列的代码中,然后替换现有的citiesArray 和致电reloadData,类似:

- (void)refresh:(UIRefreshControl *)refreshControl {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSArray *newCitiesArray = [self retreiveData];

        dispatch_async(dispatch_get_main_queue(), ^{

            if (newCitiesArray) {

                // you presumably only want to reload the data if `retrieveData` was successful

                citiesArray = newCitiesArray
                [myTableView reloadData];
            }

            [refreshControl endRefreshing];
        });
    });
}

显然,这也将涉及对retrieveData 的一些更改,但希望这是不言自明的。如果没有,请使用该代码更新您的问题,我们可以提出进一步的建议。但我们真的不需要去那里,因为我怀疑你理解那里需要发生的变化。

您可能还想解决其他更微妙的问题,例如考虑是否真的要使用全局队列,它是并发的(例如,如果您在上一次刷新进行时点击刷新,您真的希望两个查询与您的服务器同时进行......因为您将更新发送回主队列,您不会崩溃,但它效率低下,您不能保证它们完成的顺序等)。您可能还想使用NSOperationQueue,您可以在其中编写代码以允许取消先前的请求等。

但所有这些都有些复杂,并且是您的主要问题(崩溃)的次要问题。重构retrieveData 代码以确保您不会触及citiesArray,如上所述,它本身应该可以解决这个问题。

【讨论】:

  • 感谢您的回答,这确实有帮助,但我仍然有一个问题: NSArray *newCitiesArray = [self retreiveData]; 行给我错误:用“void”类型的表达式初始化“NS_Array *__strong”。为什么会这样?
  • @jrock007 要这样做,您必须将retrieveDatavoid 返回类型更改为NSArray(或者,如果您使用可变数组,则NSMutableArray) .然后更改它,使该方法不使用citiesArray,而是创建一个您将在retrieveData 中使用的新变量,并在该方法结束时返回该新数组对象(或返回nil如果您有任何网络或 JSON 解析错误)。
  • 我发现如何通过更改一些代码自行解决该问题......所以谢谢!你真的帮了我很多!
猜你喜欢
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多