如何制作一个boolean静态和__block?在iOS?

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之前添加静态,我的代码中的全局变量有什么区别?

rma*_*ddy 5

__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.