我正在设计一个iPhone应用程序。用户搜索的东西。我们从网上获取数据。然后我们更新表格。
伪代码将是
[DoThisAtbackground ^{
LoadData ();
[DoThisAtForeground ^{
UpdateTableAndView();
}];
}];
如果在第一次搜索完成之前,用户搜索其他内容。
解决问题的行业标准方法是什么?
我们究竟是怎么做到的?
答案 0 :(得分:2)
我建议你看看iOS Human Interface Guidelines。 Apple认为所有应用程序的行为都非常重要,所以他们写了一篇关于这类问题的大量文档。
在指南中,有两件事与您的问题相关:
虽然这些指南当然有很多废话,但我认为以上几点实际上是一个好主意。作为用户,我希望在搜索时能够发生一些事情,并且每当线程完成时更新视图,用户将看到最快的响应。是的,这可能是用户不想要的结果,但有些事情正在发生!例如,在iOS中使用Safari网络浏览器:即使您正在键入内容,Google自动填充功能也会显示结果,而不仅仅是在您输入完搜索查询后。
所以我认为最好选择第二种选择。
答案 1 :(得分:2)
如果您正在向远程服务器执行数据的REST请求,您可以随时取消请求并启动新请求而不更新表,这是一种方法。有时间完成的请求将更新UI,而其他请求则不会。例如,使用ASIHTTPRequest
- (void)serverPerformDataRequestWithQuery:(NSString *)query andDelegate:(__weak id <ServerDelegate)delegate {
[currentRequest setFailedBlock:nil];
[currentRequest cancel];
currentRequest = [[ASIHTTPRequest alloc] initWithURL:kHOST];
[currentRequest startAsynchronous];
}
如果您需要本地SQLite数据库的答案,请告诉我,因为它要复杂得多。
答案 2 :(得分:0)
您可以使用NSOperationQueue
取消所有待处理操作,但仍然不会取消现有操作。您仍然需要实现一些取消现有操作的东西......这也可以提前中止队列中的操作。
我通常更喜欢直接GCD,除非我的用例中有其他好处更适合NSOperationQueue
。
此外,如果您的加载具有外部取消机制,则您希望取消任何挂起的I / O操作。
如果操作是独立的,请考虑并发队列,因为它将允许较新的请求在其他(s)被取消时同时执行。
此外,如果它们都是I / O,请考虑是否可以使用dispatch_io
而不是阻止线程。正如Monk所说,“你以后会感谢我。”
考虑这样的事情:
- (void)userRequestedNewSearch:(SearchInfo*)searchInfo {
// Assign this operation a new token, that uniquely identifies this operation.
uint32_t token = [self nextOperationToken];
// If your "loading" API has an external abort mechanism, you want to keep
// track of the in-flight I/O so any existing I/O operations can be canceled
// before dispatching new work.
dispatch_async(myQueue, ^{
// Try to load your data in small pieces, so you can exit as early as
// possible. If you have to do a monolithic load, that's OK, but this
// block will not exit until that stops.
while (! loadIsComplete) {
if ([self currentToken] != token) return;
// Load some data, set loadIsComplete when loading completes
}
dispatch_async(dispatch_get_main_queue(), ^{
// One last check before updating the UI...
if ([self currentToken] != token) return;
// Do your UI update operations
});
});
}
它会提前中止任何不是最后提交的操作。如果您使用NSOperationQueue
,则可以调用cancelAllOperations
,但仍需要类似的机制来提前中止当前正在执行的那个。