【问题标题】:Static variable inside block块内的静态变量
【发布时间】:2018-03-06 06:04:51
【问题描述】:
当我在这样的块中声明一个静态变量时会发生什么?
dispatch_async(dispatch_get_main_queue(), ^{
static NSInteger myNumber;
// do stuff with myNumber
});
- 第二次触发此块时会发生什么?
- 如果块在运行后将被释放,myNumber 怎么可能仍然存在?
- 这样做可以吗?我的意思是这种做法会导致任何问题,比如因为无法释放而导致块泄漏?
【问题讨论】:
标签:
ios
objective-c
macos
cocoa
objective-c-blocks
【解决方案1】:
也许我们可以使用“C”底层逻辑来回答.. 闭包-> 块-> 指向标准 C 函数的指针,发生“C”静态逻辑-> 全局(OMG!)
【解决方案2】:
block specification 没有明确提到如何处理块内的static 变量,只是块体是一个复合语句,与函数体相同。因此语义与函数中声明的static 变量的语义相同,即它们是全局生命周期的变量,只能在声明它们的范围内通过名称直接访问。
每次评估块文字 (^{...}) 时都会构造一个块值。该值包含一个标准 C 函数指针,指向块体的已编译代码,与任何其他复合语句一样,它在编译时生成一次。
您的问题的答案就是这样:
- 第二次触发此块时会发生什么?
第二次执行带有本地 static 变量的函数时会发生同样的情况,函数体会看到先前存储在变量中的值。
- 如果块在运行后将被释放,myNumber 怎么可能仍然存在?
因为它是块值,包括任何关联的捕获变量,被释放;包含任何static 变量的编译代码始终存在。
- 这样做可以吗?我的意思是这种做法会不会导致任何问题,比如因为无法释放而导致块泄漏?
执行此操作与在函数中执行此操作相同。如果static 是Objective-C 对象类型,那么存储在其中的引用可能会“泄漏”——就像标准全局变量一样。除非您在 static 变量中存储对块本身的引用(直接或间接通过引用链),否则不会阻止释放块值。
HTH