如何使布尔值既静态又 __block?在 iOS?
How to make a boolean both static and __block? in iOS?
bool _hintExist;
- (void)showNotReachable
{
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
上面的代码没问题。有一个按钮可以触发该方法。实际上,我不需要 _hintExist 是一个全局变量。当我试图在 bool _hintExist 前面添加静态和 __block 时,我想在 method.However 中创建 bool _hintExist。会有编译错误。如果我将它设为全局变量,我可以在块中更改 _hintExist,这让我感到很惊讶。有人可以解释为什么吗?如果我在代码中的全局变量 bool _notReachableHintExist 之前添加 static 有什么区别?
__block
本质上是局部变量的作用域修饰符,允许块修改在外部作用域中声明的局部变量的值。
您的 _hintExist
变量不是局部变量。这是一个全球性的。所以不需要 __block
修饰符。该块可以访问全局变量,就像同一文件中的任何其他代码一样。
如果您只是将 static
添加到您的 _hintExist
变量,它仍然是一个全局变量,但现在仅限于此文件。并且该块与文件中的任何其他代码一样,仍然可以访问和修改文件全局变量。
另一种选择是使 _hintExist
变量成为局部静态变量,如下所示:
- (void)showNotReachable
{
static bool _hintExist = false;
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
假设它是您想要的,它也能正常工作。该变量的范围仅限于方法,但静态意味着该值独立于 class 的任何特定实例。同样,static
意味着您不需要 __block
修饰符。它就像一个全局但只在方法内部。
顺便说一句 - 关于通用命名约定的小说明。除实例变量外,不要对变量使用前导下划线。
根据安迪在此答案下方的第二条评论更新:
您似乎真的想使用实例变量,因为您希望 class 的每个实例都以 _hintExist
的 false
值开始。
将 ivar 添加到 @implementation
块:
@implementation WhateverClassThisIs {
bool _hintExist;
}
更新后的showNotReachable
方法:
- (void)showNotReachable
{
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
与全局变量和静态变量一样,实例变量不需要 __block
限定符。而且,默认情况下,_hintExist
的初始值为 false
。
bool _hintExist;
- (void)showNotReachable
{
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
上面的代码没问题。有一个按钮可以触发该方法。实际上,我不需要 _hintExist 是一个全局变量。当我试图在 bool _hintExist 前面添加静态和 __block 时,我想在 method.However 中创建 bool _hintExist。会有编译错误。如果我将它设为全局变量,我可以在块中更改 _hintExist,这让我感到很惊讶。有人可以解释为什么吗?如果我在代码中的全局变量 bool _notReachableHintExist 之前添加 static 有什么区别?
__block
本质上是局部变量的作用域修饰符,允许块修改在外部作用域中声明的局部变量的值。
您的 _hintExist
变量不是局部变量。这是一个全球性的。所以不需要 __block
修饰符。该块可以访问全局变量,就像同一文件中的任何其他代码一样。
如果您只是将 static
添加到您的 _hintExist
变量,它仍然是一个全局变量,但现在仅限于此文件。并且该块与文件中的任何其他代码一样,仍然可以访问和修改文件全局变量。
另一种选择是使 _hintExist
变量成为局部静态变量,如下所示:
- (void)showNotReachable
{
static bool _hintExist = false;
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
假设它是您想要的,它也能正常工作。该变量的范围仅限于方法,但静态意味着该值独立于 class 的任何特定实例。同样,static
意味着您不需要 __block
修饰符。它就像一个全局但只在方法内部。
顺便说一句 - 关于通用命名约定的小说明。除实例变量外,不要对变量使用前导下划线。
根据安迪在此答案下方的第二条评论更新:
您似乎真的想使用实例变量,因为您希望 class 的每个实例都以 _hintExist
的 false
值开始。
将 ivar 添加到 @implementation
块:
@implementation WhateverClassThisIs {
bool _hintExist;
}
更新后的showNotReachable
方法:
- (void)showNotReachable
{
if (_hintExist) {
return;
}
NSLog(@"Show a hint");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_hintExist = NO;
});
}
与全局变量和静态变量一样,实例变量不需要 __block
限定符。而且,默认情况下,_hintExist
的初始值为 false
。