块内的静态变量

时间:2017-09-25 09:53:37

标签: ios objective-c macos cocoa objective-c-blocks

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

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

2 个答案:

答案 0 :(得分:3)

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

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

您的问题的答案就是:

  
      
  1. 第二次触发此块时会发生什么?
  2.   

第二次执行带有本地static变量的函数时,函数体会看到先前存储在变量中的值。

  
      
  1. 如果块在运行后将解除分配,myNumber如何仍然存在?
  2.   

因为它是块值,包括任何相关的捕获变量,它们被解除分配;已编译的代码(包括任何static变量)始终存在。

  
      
  1. 这样做好吗?我的意思是这种做法会导致任何问题,例如块泄漏,因为它无法释放?
  2.   

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

HTH

答案 1 :(得分:0)

也许我们可以使用“C”底层逻辑来回答.. closure->块 - >指向std C函数的指针,发生“C”静态逻辑 - >全局(OMG!)