使用NSURLConnection进行异步调用后处理数据的更好方法是什么?

时间:2014-05-08 20:07:44

标签: ios objective-c uitableview nsurlconnection nsurlconnectiondelegate

这是我用来使用NSURLConnection填充表视图的当前逻辑。它对我来说并不优雅。

Table View Controller的viewDidLoad方法调用" sendConnection"我的api包装类中的方法,URL字符串作为参数。这个方法使NSURLConnection。在connectionDidFinishLoading(在我的包装类中),另一个方法被调用(也在包装类中),连接作为参数。此方法从连接对象中提取URL并检查它。然后它使用switch语句根据URL处理数据。数据存储在包装类本身的变量中。调用cellForRowAtIndexPath时,异步调用已完成,数据已处理完毕。

有更好的方法吗?

我提出这个问题的理由如下: 我想在单击时刷新具有新高度和新文本标签的单元格。在点击单元格时,将从服务器检索此文本标签的数据。每个单元格在标签中的数据略有不同(每个单元格代表一个用户'标签将显示您与该用户有多少共同的朋友)。我想在检索数据时将数据存储在单元格中,然后将其放入文本标签中。使用我目前的URL调用方式,这似乎无法实现。

任何有关如何实现这一目标的帮助都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

这是我喜欢在这些情况下使用的模式的一些伪代码。也许它对你也有帮助。

- (void)viewDidLoad {
     //1. put up some type of progressHud or spinner
     //2. call your NSURL wrapper
     //3. in the completion block of your wrapper, set your datasource variables
          //example: @property (nonatomic,strong) NSArray *listOfData;
     //4. create a custom setter for your datasource that calls tableview reload
     //5. enable a refresh function; like "pull to refresh" or a bar button
     //6. when pull to refresh is tapped or called, just repeat these steps


}
- (void)setListOfData:(NSArray*)listOfData {

       _listOfData = listOfData;
       if (_listOfData) {
           [self.tableView reloadData];
       }
}

当我再次阅读你的问题时,还有一些想法: 上面的模式适用于您的初始加载,创建人员或朋友的列表等。

如果您打算在敲击单元格后进行另一次往返,则必须考虑许多问题。这类似于将图像延迟加载到tableview单元格中的常见问题。有一些问题需要考虑滚动 - 如果在数据返回之前单元格从视图滚动,例如,如果单元格已被重用,如果单元格不再与该单元格相关联,该怎么办?

Github上有许多异步图像库可供查看它们如何解决这些问题。通常,他们会跟踪单元格中的项目,然后检查单元格是否仍在视图中,如果是,则设置图像。

您有类似的问题需要解决。点击单元格,获取新数据,然后更新单元格。调整单元格大小将需要您重新加载它。

使用RowAnimation查看[tableview reloadRowsAtIndexPaths:(NSArray *):( UITableViewRowAnimation)];

希望有所帮助 祝福;

答案 1 :(得分:1)

你应该有一个"数据模型"表示表视图的内容(即单元格)。

因为你有"行"在您的表视图中,有意义的是,这个数据模型是一种数组(可能是NSArray),其元素保存单元格的数据和状态

每个小区的数据不仅应该包含所有数据"在您的单元格中呈现的属性(例如标签),还有其状态

当用户选中单元格时,它将启动异步任务。此任务可能需要一段时间才能完成,因为它从远程服务器获取数据。想想几秒钟,甚至更长时间。您需要跟踪挂起更新任务,因为您的实现应该阻止用户在相应的挂起更新任务完成之前再次更新单元格。

有几种技术可以实现这一目标。一种方法是在你的" Cell Data"反映这种状态的类,例如:

@interface CellModel : NSObject    
@property (atomic) BOOL hasPendingUpdate;
...

当渲染单元格时,您将检索属性的值并适当地渲染单元格。

更新任务完成后,会更新其单元模型数据。

模型更新最终将更新您的表视图。有几种技术可以实现这一目标。你应该在这里注意线程安全和"同步"您的数据模型和表格视图单元格。例如,确保hasPendingUpdate的值仅在主线程上发生变化 - 否则您的渲染单元格可能与数据模型不同步(更不用说在您修改和访问不同线程上的属性时的竞争条件)没有同步原语)。

当单元格等待更新时,它应该直观地指示此状态(例如使用微调器)并禁用该操作以启动更新任务。

非常推荐的是"取消"按钮,取消某个单元格更新任务或所有挂起的更新任务。

当用户离开此视图时,您可以考虑取消所有待处理任务。