块内的静态变量

Static variable inside block

当我像这样在块中声明静态变量时会发生什么?

dispatch_async(dispatch_get_main_queue(), ^{
 static NSInteger myNumber;
 // do stuff with myNumber      
});
  1. 第二次触发此块会发生什么?
  2. 如果块将在 运行 后解除分配,myNumber 怎么可能还在那里?
  3. 这样做可以吗?我的意思是这种做法会导致任何问题,比如因为无法释放而导致块泄漏吗?

block specification没有明确提到static块中的变量是如何处理的,只是说块体是一个复合语句,与函数体相同。因此语义与函数中声明的 static 变量相同,即它们是全局生命周期的变量,只能在它们声明的范围内通过名称直接访问。

每次评估块文字^{...})时都会构造一个块。这个值包含一个标准的 C 函数指针,指向块体的编译代码,它像任何其他复合语句一样在编译时生成一次。

您的问题的答案就是:

  1. What happens the second time this block is triggered?

第二次执行具有局部 static 变量的函数时会发生同样的事情,函数体会看到先前存储在变量中的值。

  1. How can myNumber be still there if the block will deallocate after running?

因为它是块值,其中包括任何关联的捕获变量,它被释放;包含任何 static 个变量的编译代码始终存在。

  1. Is doing this OK? I mean will this practice cause any problem, like the block leaking because it is unable to be released?

这样做与在函数中进行相同。如果 static 是 Objective-C 对象类型,那么存储在其中的引用可能 "leak" - 就像标准全局变量一样。除非您在 static 变量中存储对块本身的引用(直接或间接通过引用链),否则不会阻止块值的释放。

HTH

也许我们可以使用 "C" 底层逻辑来回答。闭包-> 块 -> 指向标准 C 函数的指针,指向 "C" 静态逻辑发生-> 全局变量(OMG!)