重载表视图:indexPath未重置ios 6

时间:2013-07-30 13:56:53

标签: iphone uitableview ios6 reload

我正在制作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

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

1 个答案:

答案 0 :(得分:0)

跳出的关键设计考虑因素是您的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,如上所述,应该解决这个问题。