美文网首页
iOS中的Block访问变量使用注意问题

iOS中的Block访问变量使用注意问题

作者: Simon_____ | 来源:发表于2018-09-21 14:31 被阅读0次

    一、Block内访问局部变量

    int main(int argc, char * argv[]) {
    int global = 100;
    void (^myBlock)() = ^{
    NSLog(@"global = %d", global);
    };
    // 控制台输出 global = 100
    myBlock();
    return 0;
    }
    

    a、在声明block后,调用block之前对局部变量修改,block里面扑获的值仍是修改之前的值

    在Block定义时便是将局部变量的值传给Block变量所指向的结构体,因此在调用Block之前对局部变量进行修改并不会影响Block内部的值,同时内部的值也是不可修改的

    int main(int argc, char * argv[]) {
    int global = 100;
    void (^myBlock)() = ^{
    NSLog(@"global = %d", global);
    };
    global = 101;
    // 控制台输出修改之前的 global = 100[
    myBlock();
    return 0;
    }
    

    b、在block中不可以直接修改局部变量

    int main(int argc, char * argv[]) {
    int global = 100;
    void (^myBlock)() = ^{
    // 提示错误
    global ++;
    NSLog(@"global = %d", global);
    };
    return 0;
    }
    
    

    <font color=#ff0000>main.m:17:16: Variable is not assignable (missing __block type specifier)</font>

    c、__block修饰

    以上错误提示需要我们用__block对变量进行修饰,修饰后无报错且修改成功。
    在局部变量前使用__block修饰,在Block定义时便是将局部变量的指针传给Block变量所指向的结构体,因此在调用Block之前对局部变量进行修改会影响Block内部的值,同时内部的值也是可以修改的

    int main(int argc, char * argv[]) {
    __block int global = 100;
    void (^myBlock)() = ^{
    // 控制台输出 global = 101
    global ++;
    NSLog(@"global = %d", global);
    };
    myBlock();
    return 0;
    }
    

    a中变量用__block修饰后,调用block之前对局部变量修改,block里面扑获的值是修改之后的值。

    二、Block内访问全局变量

    全局变量所占用的内存只有一份,供所有函数共同调用,在Block定义时并未将全局变量的值或者指针传给Block变量所指向的结构体,因此在调用Block之前对局部变量进行修改会影响Block内部的值,同时内部的值也是可以修改的

    a、在声明block后,调用block之前对局全局变量修改,block里面扑获的值是修改之后的值

    int global = 100;
    int main(int argc, char * argv[]) {
    void (^myBlock)() = ^{
    // 控制台输出 global = 101
    NSLog(@"global = %d", global);
    };
    global = 101;
    myBlock();
    return 0;
    }
    

    b、在block中可以直接修改全局变量

    int global = 100;
    int main(int argc, char * argv[]) {
    void (^myBlock)() = ^{
    global ++;
    // 控制台输出 global = 101
    NSLog(@"global = %d", global);
    };
    myBlock();
    return 0;
    }
    

    三、Block内访问静态变量

    a、在block内可以访问静态变量。

    b、在声明block之后、调用Block之前对静态变量进行修改,在调用block时静态变量值是修改之后的新值

    int main(int argc, char * argv[]) {
    static int global = 100;
    void (^myBlock)() = ^{
    // 控制台输出 global = 101
    NSLog(@"global = %d", global);
    };
    global = 101;
    myBlock();
    return 0;
    }
    

    c、在block中可以直接修改全局变量

    int main(int argc, char * argv[]) {
    static int global = 100;
    void (^myBlock)() = ^{
    global ++;
    // 控制台输出 global = 101
    NSLog(@"global = %d", global);
    };
    myBlock();
    return 0;
    }
    

    总结:对于block使用和修改变量,主要还是看block里面扑获的是变量的值还是变量的指针。局部变量扑获的是值,全局和静态则是指针。另外使用block要注意的地方就是循环引用导致的内存泄漏问题。

    参考文章

    相关文章

      网友评论

          本文标题:iOS中的Block访问变量使用注意问题

          本文链接:https://www.haomeiwen.com/subject/pjwanftx.html