的iOS:dispatch_block_t执行一些代码部分两次,我不知道为什么

问题描述:

当我调用下面的函数:的iOS:dispatch_block_t执行一些代码部分两次,我不知道为什么

+ (void) myMethod:(NSString *) myConstString array: (NSArray *) myArray 
{ 
    dispatch_block_t block = 
    ^{ 
     for (int i = 0; i < myArray.count; i++) 
     { 
      if ([@"myString1" isEqual: myConstString]) 
       // Do some easy job here 

      else if ([@"myString2" isEqual: myConstString]) 
       // Do some other easy job here 

      [NSThread sleepForTimeInterval: 0.5]; 
     } 

     [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil userInfo:nil]; 
    }; 

    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.test", NULL); 
    dispatch_async(backgroundQueue, block); 
} 

[[NSNotificationCenter...]执行两次。我知道,因为负责“捕获”此通知的其他类中的方法被称为两次。第一个电话是即时的(这对我来说很奇怪)。第二个电话是约2秒(这个电话我喜欢:-))后,我知道该怎么“修理”这样的:

+ (void) myMethod:(NSString *) myConstString array: (NSArray *) myArray { 
    dispatch_block_t block = 
    ^{ 
     Boolean isForLoopExecuted = false; 
     for (int i = 0; i < myArray.count; i++) 
     { 
      if ([@"myString1" isEqual: myConstString]) 
       // Do some easy job here 

      else if ([@"myString2" isEqual: myConstString]) 
       // Do some other easy job here 

      [NSThread sleepForTimeInterval: 0.5]; 
      isForLoopExecuted = true; 
     } 
     if (isForLoopExecuted) 
      [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil userInfo:nil]; 
    }; 

    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.test", NULL); 
    dispatch_async(backgroundQueue, block); } 

addind后isForLoopExecuted一切正常propertly。 2秒后只有一个呼叫。这表明for循环在第一次调用时不会执行。我很好奇为什么会发生这种情况。谢谢你的时间!

+0

你有没有交叉验证过,你没有从代码中的任何其他地方发射相同的通知?添加一个变量来检查执行没有意义。如果block得到执行,你的通知将被调用。 – Gandalf 2014-12-05 09:50:00

首先,每次该函数运行时创建新的后台队列可能都不是您想要的。限制你可以拥有多少队列,并且这是迅速达到这个限制和崩溃的正确方法。 使用像这样的:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY,0),block);

其次,第一个列表没有错(除了背景队列)并且它能正常工作。通知只会发送一次。

我建议的是当你发送通知的时候把日志放到你正在执行那个函数的次数。可能不止一次。此外,将在队列中花费的时间取决于您在那里发送的参数。如果myArray为空,您几乎可以立即收到通知。

+0

谢谢你的回答。你能解释我如何dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY,0),块);作品? – 2014-12-05 13:26:34

+0

dispatch_get_global_queue将返回您可以使用的系统后台队列。您只需指定优先级,在本例中我使用了QOS_CLASS_UTILITY。我建议查看关于并发编程的文档:https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html – 2014-12-05 13:34:21