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

Ios 如何检查全局调度队列是否为空?,ios,objective-c-blocks,grand-central-dispatch,uiapplication,Ios,Objective C Blocks,Grand Central Dispatch,Uiapplication,在我的应用程序中,我使用全局调度队列和gcd来实现我的互联网网络。 我想在有网络活动时将网络指示器设置为可见 这是我的网络块-> { [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES]; send sync http request [[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO]; } 我的问题

在我的应用程序中,我使用全局调度队列和gcd来实现我的互联网网络。 我想在有网络活动时将网络指示器设置为可见

这是我的网络块->

{
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];

send sync http request

[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];


}
我的问题是:

  • 我想检查是否有块尚未执行!在隐藏网络指示器之前。我怎么能实现呢

  • 从另一个线程调用setNetworkActivityIndicatorVisible是否安全,因为我看到NetworkActivityIndicatorVisible是非原子的


  • 一种可能的方法是创建一组任务,然后等待它们完成。在开始和结束之间,您可以更新活动指示器。显然,您需要一些对象来保留对组的引用。根据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);
    

    请记住,您可以使用一个单例对象来分派块并跟踪等待。

    @DavidBemerguy的方法是一个很好的开始,但您通常希望使用
    dispatch\u group\u notify
    来实现它,以隐藏指示器。也就是说,依我看,这里不需要GCD。您只需要一个
    网络指示器控制器

    创建侦听通知的对象(控制器),如
    DidStartNetworkActivity
    DidStopNetworkActivity
    。启动或停止时发布通知。在控制器内部,保持计数,当它达到0时,隐藏指示器。类似这样的内容(完全未经测试,只需在此处键入,过去几天我一直在用Swift独家写作,请原谅任何缺少的分号):

    .h:

    m

    @接口网络指示器控制器()
    @属性(非原子、读写、赋值)NSInteger计数;
    @结束
    @实现网络指示器控制器
    -(无效)开始{
    NSNotificationCenter*nc=[NSNotificationCenter defaultCenter];
    [nc addObserver:self name:DidStartNetworkActivityNotification选择器:@selector(didStart:)对象:nil];
    [nc addObserver:自身名称:DidStopNetworkActivityNotification选择器:@selector(didStop:)对象:nil];
    self.count=0;
    }
    -(无效)停止{
    NSNotificationCenter*nc=[NSNotificationCenter defaultCenter];
    [nc removeObserver:自身名称:DidStartNetworkActivityNotification对象:nil];
    [nc removeObserver:自身名称:DidStopNetworkActivityNotification对象:nil];
    }
    -(无效)didStart:(NSNOTITION*)注释{
    dispatch\u async(dispatch\u get\u main\u queue(){
    self.count=self.count+1;
    [[UIApplication sharedApplication]设置网络活动指示器可见:是];
    });
    }
    -(无效)didStop:(NSNOTITITION*)注释{
    dispatch\u async(dispatch\u get\u main\u queue(){
    self.count=self.count-1;
    
    如果(self.count问题#1的答案很简单,如果您更高一级并使用NSOperationQueue。向其提交块实际上并不比GCD困难,它可以让您更好地控制操作。@PhillipMills谢谢,我将检查documentation@PhillipMills但是第二个问题呢?我不知道,我更喜欢我对我实际使用过的东西发表了评论。:@PhillipMills谢谢你这是正确的方式。就我所知,记录在案的是,(至少目前是这样)没有用于确定任意GCD队列是否为空的公共API。即使您可以询问队列是否为空,也没有用,因为从您检查到您对其采取措施期间,队列可能不再为空。更糟糕的是,其他队列可能会以此队列为目标,并可以更改其目标队列。问题是如果针对某个队列的某些队列被挂起但有阻塞,则该队列是否为空。您可以通过调度组解决所有这些问题,但您必须决定您想要的答案是什么,这可能需要大量工作:Dell说,Rob。说得好。:)
    extern NSString * const DidStartNetworkActivityNotification;
    extern NSString * const DidStopNetworkActivityNotification;
    
    @interface NetworkIndicatorController
    - (void) start;
    - (void) stop;
    @end
    
    @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];
          }
        });
    }