2013-07-03 56 views
0

我正在构建的应用程序有很多表。我正在加载前15行的数据,当用户向下滚动时,我得到下一批15行。DBAccess与异步

我已经写了一些DBAccess函数,需要一个“计数”和“跳过”。最初加载表时,count = 15,skip = 0。当用户滚动时,count = 15,skip = [array count];

的代码是这样的:

- (void)getDataWithCount:(NSInteger)count withSkip:(NSInteger)skip 
{ 
    if (skip == 0) 
     self.dataArray = [[NSMutableArray alloc]init]; 

    [DBAccess getData:self.dataArray withCount:count withSkip:skip handler:^(void) 
    { 
     if (no error) 
      [table reloadData]; 
    }]; 
} 

我得到阵列出界的崩溃中的cellForRowAtIndexPath上很慢的网络连接(例如,索引16超出空数组numberOfRowsInSection返回[阵列计数])。

我觉得问题如下:

0)进入屏幕。

1)负载15行

2)向下滚动,加载另一个15.连接速度慢,所以我不从我sendAsynchronousRequest DB调用

3接到一个电话回来了)转到另一个视图 - 控制(即离开屏幕,我可以这样做,因为异步不会冻结我的屏幕)。

4)回到屏幕上。加载初始屏幕设置skip = 0,因此初始化我的可变数组,命中数据库

5)从步骤2返回的数据库命中。我的可变数组现在已经从第4步设置为零。重载表时,它试图获取self.dataArray objectAtIndex:16等,当数组现在为空时,从if(skip == 0)初始化

这似乎是正确的?任何其他原因,如果numberOfRowsInSection正在返回[数组计数];为什么我会有数组越界?有没有一个首选的方法来解决这个问题?

回答

0

很难说所提供的有限信息,但很难调和第5点,即您的数组已重新初始化,但您的数据库请求仍在进行中。如果支持该表的模型对象被重置,则数据库查询不应该仍在运行。或者:

  • 一旦模型对象出去的范围(例如,使用操作队列,其中,如果所述操作被设计属性,是取消,而不是GCD),你应该取消了异步数据请求;或

  • 您应该将某个缓存机制中的模型对象保留下来,以便在异步数据请求完成时,当您在步骤4中返回控制器时,您已经将数据缓存并准备好显示。

就其他潜在的问题来源而言,我想知道您的异步数据更新过程是否真的是线程安全的。您是否将您的交互与异步更新的属性同步?这种同步通常通过一些locking mechanism或通过dedicated serial queue(或在读取器/写入器模式中使用并发队列)来完成。线程安全是一个不平凡的问题,我想知道你对这个分数有多自信。