Objective c 当用户在等待下载时多次生成相同的操作时,该怎么办?

Objective c 当用户在等待下载时多次生成相同的操作时,该怎么办?,objective-c,multithreading,web-services,Objective C,Multithreading,Web Services,我正在设计一个IPhone应用程序。用户搜索一些东西。我们从网上获取数据。然后我们更新表 伪代码应该是 [DoThisAtbackground ^{ LoadData (); [DoThisAtForeground ^{ UpdateTableAndView(); }]; }]; 如果在第一次搜索完成之前,用户搜索了其他内容呢 行业标准的解决方法是什么 跟踪哪个线程仍在运行,只更新表 所有线程何时完成 每次线程完成时更新视图 我们到底是如何做到这一点的?我建议你看一下。苹果

我正在设计一个IPhone应用程序。用户搜索一些东西。我们从网上获取数据。然后我们更新表

伪代码应该是

[DoThisAtbackground ^{
  LoadData ();
  [DoThisAtForeground ^{
    UpdateTableAndView();
  }];
}];
如果在第一次搜索完成之前,用户搜索了其他内容呢

行业标准的解决方法是什么

  • 跟踪哪个线程仍在运行,只更新表 所有线程何时完成
  • 每次线程完成时更新视图

  • 我们到底是如何做到这一点的?

    我建议你看一下。苹果认为所有应用程序的行为方式都差不多是很重要的,所以他们已经写了一份关于这类问题的详细文档

    在指南中,有两件事与您的问题相关:

    • :“如果可能,还可以在用户键入时筛选远程数据。虽然筛选用户键入的内容可以带来更好的搜索体验,但如果响应时间可能会延迟结果一两秒以上,请务必通知他们并给他们选择退出的机会。”
    • :“反馈确认人们的行为,并向他们保证正在进行处理。人们希望在操作控件时立即得到反馈,并且他们希望在长时间的操作过程中得到状态更新。”
    虽然这些指导方针中当然有很多废话,但我认为以上几点实际上是一个值得遵循的好主意。作为一个用户,我希望在搜索时会发生一些事情,当每次线程完成时更新视图时,用户将看到最快的响应。是的,这可能是用户不想要的结果,但是发生了一些事情!例如,以iOS中的Safari web浏览器为例:Google autocomplete即使在您键入时也会显示结果,而不仅仅是在您输入完搜索查询后


    因此,我认为最好使用第二个选项。

    如果您正在对远程服务器执行REST数据请求,您可以随时取消请求并启动新请求,而无需更新表,这是一种方法。有时间完成的请求将更新UI,而其他请求则不会。例如,使用ASIHTTPRequest

    - (void)serverPerformDataRequestWithQuery:(NSString *)query andDelegate:(__weak id <ServerDelegate)delegate {
      [currentRequest setFailedBlock:nil];
      [currentRequest cancel];
      currentRequest = [[ASIHTTPRequest alloc] initWithURL:kHOST];
      [currentRequest startAsynchronous];
    }
    

    -(void)服务器PerformDataRequestWithQuery:(NSString*)查询和委派:(uu弱id您可以使用
    NSOperationQueue
    取消所有挂起的操作,但它仍然不会取消现有操作。您仍然需要实施一些措施来取消现有操作…这也可以提前中止队列中的操作

    我通常更喜欢直接的GCD,除非在我的用例中有其他更适合
    NSOperationQueue
    的好处

    此外,如果加载具有外部取消机制,则需要取消任何挂起的I/O操作

    如果操作是独立的,考虑并发队列,因为它将允许新的请求同时执行,因为其他的(S)被取消。

    此外,如果它们都是I/O,那么考虑是否可以使用<代码> DeXCHOXIO而不是阻塞线程。 考虑一下这样的情况:

    - (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
    ,但你仍然需要一个类似的机制来提前中止当前正在执行的操作。

    踢用户,或者用重击他:)我讨厌这些不耐烦的混蛋;)好问题。那么,自动完成呢?用户输入速度非常快,每次输入都会从网络上获取一些信息。我有一个系统,我们可以跟踪线程的数量。车还开着。我可以将其作为答案发布。禁用(并更改)任何正在进行操作的按钮。这是个好主意。我真的想避免终止任何线程。每次线程结束时,我都会更新线程计数器或保存托管对象上下文。过早终止线程将带来难以调试的问题。