取消NSJSONSerialization - 在键入时搜索,请求重叠

时间:2013-04-09 13:58:18

标签: ios xcode nsurlconnection nsjsonserialization

与iPhone Facebook应用搜索功能类似,我在我的应用程序中键入功能时实现搜索,尽管在将数据解码为JSON格式时遇到问题。

基本上发生的事情是因为某些搜索比其他搜索花费的时间更长,它们会以不同的间隔返回,这会在屏幕上显示数据时导致一些小的视觉问题。

我在每次解码后使用NSJSONSerialization为关键字'industry'设置了一个NSLOG

2013-04-09 23:38:18.941 Project Name [42836:1d03] http://fooWebAddress/json/?method=search&limit=10&q=indus
2013-04-09 23:38:19.776 Project Name [42836:3e07] http://fooWebAddress/json/?method=search&limit=10&q=indu
2013-04-09 23:38:20.352 Project Name [42836:8803] http://fooWebAddress/json/?method=search&limit=10&q=indust
2013-04-09 23:38:21.814 Project Name [42836:4e03] http://fooWebAddress/json/?method=search&limit=10&q=industr
2013-04-09 23:38:23.434 Project Name [42836:8803] http://fooWebAddress/json/?method=search&limit=10&q=ind
2013-04-09 23:38:24.070 Project Name [42836:7503] http://fooWebAddress/json/?method=search&limit=10&q=industry

正如你所看到的,它完全没有问题。

有没有人有办法停止以前连接的NSJSONSerialization。 或者可能以其他方式解决这个问题?


升级到NSJSONSerialization ......

  1. NSURLRequest(initwithURL)
  2. NSOperationQueue
  3. NSURLConnection(异步)
  4. NSJSONSerialization
  5. 提前致谢。

4 个答案:

答案 0 :(得分:1)

当用户开始输入更多文本时,可以取消之前的连接,并忽略从中收到的任何进一步的委托回调。然后为当前文本发出新请求。

您可以通过维护某种lastRequestlastOperation引用来实现此目的。当用户开始输入时,请调用[self.lastRequestOrOperation cancel]并忽略来自该请求的任何进一步通知,并在您拥有的任何回调中使用if (request != self.lastRequest) { return; }之类的支票。

然而,这有一个问题,即如果用户持续输入一段时间,您会不断取消请求,并且在他们停止输入之前他们可能看不到任何结果。

更好的解决方案是添加排序,以便每个请求与不断增加的序列ID相关联。然后,只有当响应的序列高于您收到的最后一个序列时,才会解析结果并更新UI。如果您收到之前的任何带外响应,则只需忽略它们。

答案 1 :(得分:0)

这是一个比取消NSJSONSerialization更复杂的问题。我的建议是使用NSFetchedResultsController填充显示搜索结果的表格视图。将搜索字词用作NSFetchRequest附加到NSFetchedResultsController的谓词变量之一。然后,当您使用NSJSONSerialization解析结果时,将结果存储为与该请求关联的搜索词。一旦搜索词发生变化(您可以在用户输入更多字符时检测到),请重新创建NSFetchedResultsController并重新加载表格视图。此外,如果使用performSelector:withObject:afterDelay启动它,您还可以尝试取消调用以解析以前的结果。请注意,由于您尝试取消时可能已启动呼叫,因此无法始终依赖此功能。

答案 2 :(得分:0)

有点基本,但您可以随时维护一个子类NSURLRequests的nsdictionary(子类提供标签)。

开始请求 - 使用tag = array.count - 1向带有密钥匹配标记的dicationary添加请求 连接返回 - 请求是最近的请求,如果是,请解析json 解析JSON - 是最近请求的请求,如果是,则显示结果,如果没有,仅在没有显示先前结果时显示 请求处理 - 从字典中删除密钥

最近的request =字典是否包含具有更高键值的对象

答案 3 :(得分:0)

目前您正在做的是,键入每个字符并调用Web服务。为什么要为您键入的每个字母调用Web服务。如果用户连续输入,则会增加负载,因此仅当用户停留特定时间间隔时才调用Web服务。然后传递该字符串以调用Web服务或您正在调用的方法。

[NSObject cancelPerformSelectorsWithTarget:self]; // This will cancel your all req which is going to make when user typing without stopping 
[self performSelector:@selector(sendSearchRequest) withObject:searchText afterDelay:0.1f]; // This will pass the string to call a web-service method, on which user hold for some time.