A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© will123 中级黑马   /  2016-10-11 20:03  /  1561 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1.声明的变量为局部变量
int main(int argc, const charchar * argv[]) {  
    @autoreleasepool {  
        int a = 10,b = 10;  
        int (^myBlock) () = ^()  
        {  
            return a+ b;  
        };  
        int c = myBlock();  
        NSLog(@"a + b = %d", c);  
        a = 20;  
        b = 20;  
        c = myBlock();  
        NSLog(@"a + b = %d", c);  
    }  
    return 0;  
}
2016-10-11 11:25:27.892 block[893:34865] a + b = 20  
2016-10-11 11:25:27.894 block[893:34865] a + b = 20  
可以看到两次输出的结果都是20,即使我们修改了 a 和 b的值
这个问题可以这样理解,我们在创建了 block 的时候,这段代码并没有执行, block 只有在调用的时候才会去执行代码块里面的内容,因为声明的 a和 b 的变量是局部变量,在调用 block 的时候,只会读取到 a和 b 都为10 的值 想要解决这个问题我们可以将局部变量改为全局变量,静态变量也是同理
2.声明的变量为全局变量或静态变量
int a = 10,b = 10;  
int main(int argc, const charchar * argv[]) {  
    @autoreleasepool {  

        int (^myBlock) () = ^()  
        {  
            return a+ b;  
        };  
        int c = myBlock();  
        NSLog(@"a + b = %d", c);  
        a = 20;  
        b = 20;  
        c = myBlock();  
        NSLog(@"a + b = %d", c);  
    }  
    return 0;  
}  
2016-10-11 11:37:15.019 block[926:37464] a + b = 20  
2016-10-11 11:37:15.020 block[926:37464] a + b = 40  
3.在 block 中改变参数
  block 虽然可以读取 block 外部的值,但是却无法修改.因为 block 是将变量的值 copy 一份然后读取,因而想要在 block 内部修改传进来的参数,要在声明变量的时候在前面加上__block
int main(int argc, const charchar * argv[]) {  
    @autoreleasepool {  
        int b = 10;  
        __block int a = 10;  
        int (^myBlock) () = ^()  
        {  
            a += 10;  
            return a+ b;  
        };  
        int c = myBlock();  
        NSLog(@"a + b = %d", c);  
        a = 20;  
        b = 20;  
        c = myBlock();  
        NSLog(@"a + b = %d", c);  
    }  
    return 0;  
}  
2016-10-11 11:47:48.057 block[1002:41160] a + b = 30  
2016-10-11 11:47:48.058 block[1002:41160] a + b = 40  
  __block就相当于给变量赋予了一个指针,这样在 block 中使用的时候,传过来的不再是变量的copy值,而直接传递过来的是变量的地址,这样我们就可以直接修改数据本身,在调用过 block 之后再去读取变量a 的值,也会发现 a 的值已经发生了变化
  注:该问题的警告是Variable is not assignable(missing __block type specifier)
4、在代码块中使用局部变量和全局变量
在代码块中可以使用和改变全局变量
[cpp] view plain copy
int global = 1000;  
int main(int argc, const char * argv[])  
{  
    @autoreleasepool {  
        void(^block)(void) = ^(void)  
        {  
            global++;  
            NSLog(@"global:%d", global);  
        };  
        block();  
        NSLog(@"global:%d", global);  
    }  
    return 0;  
}  
运行打印结果:
global:1001
global:1001
而局部变量可以使用,但是不能改变。
[cpp] view plain copy
int local = 500;  
void(^block)(void) = ^(void)  
{  
      local++;  
    NSLog(@"local:%d", local);  
};  
block();  
NSLog(@"local:%d", local);  
在代码块中改变局部变量编译不通过。怎么在代码块中改变局部变量呢?在局部变量前面加上关键字:__block
[cpp] view plain copy
__block int local = 500;  
void(^block)(void) = ^(void)  
{  
    local++;  
    NSLog(@"local:%d", local);  
};  
block();  
NSLog(@"local:%d", local);  
运行结果:local:501
运行结果:local:501








点评

学习了!感谢!  发表于 2016-11-10 10:32

2 个回复

倒序浏览
对block还是蒙蒙的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马