从另一个View Controller中停止dispatch_async内的无限while循环

时间:2014-08-01 02:42:01

标签: ios objective-c nsurlconnection grand-central-dispatch long-polling

我正在构建一个简单的聊天室应用程序,其中我有一个NSURLConnection sendSynchronousRequest:向服务器发送请求长轮询。我希望在后台运行时显示一条始终为我的用户更新聊天Feed的流。

我的应用程序还允许用户更改聊天室,我需要关闭一个NSURLConnection并为相应的Feed打开另一个。

我目前的实施如下:

//in ViewController.m

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(concurrentQueue, ^{
            while (longPollBOOL){
            NSArray *MSG = [self.currentChatFeed longPoll]; //infinitely call longPoll method
                dispatch_sync(dispatch_get_main_queue(), ^{
                    if (MSG.count != 0) //if the longPoll method returns a non-empty array, stick it into the message feed on the device.
                    {
                        for (id element in MSG)
                        {
                            [self.messages addObject:element];
                            [self finishReceivingMessage];
                        }
                    }
                });
            }

        });

我试图通过设置我的BOOL = NO来杀死while循环,但它不起作用。 BOOL = NO正由应用程序中的另一个View Controller发送。我想保证在为另一个聊天室开始另一个无限循环之前停止这个循环。

在我开始另一个长轮询流程之前,我想在一个给定的聊天室中杀死这个漫长的民意调查流程。任何IDeas?

我这样做是否正确?

1 个答案:

答案 0 :(得分:2)

如果您想要一个可取消的任务,最好使用NSOperation对其进行建模。您可以轻松地执行此操作而无需子类化:

NSBlockOperation *blockOperation = [[NSBlockOperation alloc] init];

__weak __typeof(blockOperation) weakBlockOperation = blockOperation;

[blockOperation addExecutionBlock:^{
  while (!weakBlockOperation.isCancelled) {
    NSArray *MSG = [self.currentChatFeed longPoll]; //infinitely call longPoll method
    dispatch_sync(dispatch_get_main_queue(), ^{
      if (MSG.count > 0) {
        for (id element in MSG) {
          [self.messages addObject:element];
          [self finishReceivingMessage];
        }
      }
    });
  }
}];

[queue addOperation:blockOperation];

您只需要保留对您的操作的引用,您可以随时取消它。