And*_*win 0 objective-c static-variables objective-c-blocks
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;
});
}
Run Code Online (Sandbox Code Playgroud)
上面的代码很好.有一个按钮可以触发该方法.实际上,我不需要_hintExist是一个全局变量.我想在方法中制作bool _hintExist.但是,当我尝试在bool _hintExist前添加static和__block时.会有编译错误.令我惊讶的是,如果我把它变成一个全局变量,我可以在块中更改_hintExist.有人能解释为什么吗?如果我在bool _notReachableHintExist之前添加静态,我的代码中的全局变量有什么区别?
__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;
});
}
Run Code Online (Sandbox Code Playgroud)
这也适用于假设它是你想要的.该变量仅作用于方法,但是静态意味着该值独立于该类的任何特定实例.再次,static意味着你不需要__block修饰符.它就像一个全局但只在方法内部.
BTW - 关于常见命名约定的次要注释.除实例变量外,不要对变量使用前导下划线.
基于Andy在此答案下方的第二条评论进行更新:
您似乎确实想要使用实例变量,因为您希望类的每个实例都以其自己的false值开头_hintExist.
将ivar添加到@implementation块中:
@implementation WhateverClassThisIs {
bool _hintExist;
}
Run Code Online (Sandbox Code Playgroud)
并更新的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;
});
}
Run Code Online (Sandbox Code Playgroud)
与全局变量和静态变量一样,实例变量不需要__block限定符.并且,默认情况下,_hintExist初始值为false.