如何检查全局调度队列是否为空?

时间:2014-09-02 12:53:02

标签: ios objective-c-blocks grand-central-dispatch uiapplication

在我的应用中,我正在使用全局调度队列 gcd 来实现我的互联网网络。 我想在网络活动时设置网络指示器。

这是我的网络块 - >

{
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];

send sync http request

[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];


}

我的问题:

  1. 我想检查是否有一块尚未执行的块!隐藏网络指示器之前。我该怎么做呢!

  2. 从另一个线程调用setNetworkActivityIndi​​catorVisible,这是安全的,因为我看到NetworkActivityIndi​​catorVisible是非原子的。

2 个答案:

答案 0 :(得分:2)

@ DavidBemerguy的方法是一个良好的开端,但您通常希望使用dispatch_group_notify来实现它以隐藏您的指标。也就是说,IMO,你不需要这里的GCD。您只需要一个NetworkIndicatorController

创建一个侦听DidStartNetworkActivityDidStopNetworkActivity等通知的对象(控制器)。开始或停止时发布通知。在控制器内部,保持计数,当它达到0时,隐藏指示器。这样的事情(完全未经测试,只是在这里打字,过去几天我一直在Swift中写作,所以原谅任何丢失的分号):

·H:

extern NSString * const DidStartNetworkActivityNotification;
extern NSString * const DidStopNetworkActivityNotification;

@interface NetworkIndicatorController
- (void) start;
- (void) stop;
@end

的.m

@interface NetworkIndicatorController ()
@property (nonatomic, readwrite, assign) NSInteger count;
@end

@implementation NetworkIndicatorController

- (void)start {
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self name:DidStartNetworkActivityNotification selector:@selector(didStart:) object:nil];
    [nc addObserver:self name:DidStopNetworkActivityNotification selector:@selector(didStop:) object:nil];
    self.count = 0;
}

- (void)stop {
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc removeObserver:self name:DidStartNetworkActivityNotification object:nil];
    [nc removeObserver:self name:DidStopNetworkActivityNotification object:nil];
}

- (void)didStart:(NSNotification *)note {
    dispatch_async(dispatch_get_main_queue(),  {
      self.count = self.count + 1;
      [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
    });
}

- (void)didStop:(NSNotification *)note {
    dispatch_async(dispatch_get_main_queue(),  {
      self.count = self.count - 1;
      if (self.count <= 0) {
         [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
      }
    });
}

您可以使用dispatch_group获得类似的东西,但我认为这更简单。调度组方法的问题是跟踪您何时执行并且不想调用dispatch_notify。我确定最终的代码并不难,但考虑所有可能的竞争条件会更加棘手。

您也可以直接在您传递的此对象的实例上直接调用-startNetworkActivity-stopNetworkActivity,而不是使用通知。

答案 1 :(得分:1)

一种可能的方法是创建一组任务,然后等待它们完成。在开始和结束之间,您可以更新活动指示器。显然,您需要一些能够保留对该组的引用的对象。根据Apple文档检查此代码:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // Retain this queue somewhere accessible from the places you want to dispatch
dispatch_group_t group = dispatch_group_create(); // Retain this group somewhere accessible from the places you want to dispatch

// Add a task to the group
dispatch_group_async(group, queue, ^{
  // Some asynchronous work
});

// Do some other work while the tasks execute.
disptach_sync(dispatch_get_main_queue(), ^{
    [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
}


// When you cannot make any more forward progress,
// wait on the group to block the current thread.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

// Release the group when it is no longer needed.
disptach_sync(dispatch_get_main_queue(), ^{
    [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
}

dispatch_release(group);

请记住,您可以拥有一个单独的对象来分配您的块并跟踪您的等待。