-
Block是iOS中一种比较特殊的数据类型
-
Block的作用
- 用来保存某一段代码, 可以在恰当的时间再取出来调用
- 功能类似于函数和方法
格式
返回值类型 (^block变量名)(形参列表) = ^(形参列表) {
};
- 没有返回值,也没有形参
void (^roseBlock) ();
// 如果block没有参数, 那么^后面的()可以省略
//roseBlock =
//等号右边就是block要赋的值
roseBlock = ^(){
printf(" {@} \n");
printf(" | \n");
printf(" \\|/ \n");
printf(" | \n");
};
// 要想执行block保存的代码, 必须调用block才会执行
roseBlock();
- 没有返回值,有形参
void (^roseBlock) (int);
roseBlock = ^(int num){
for (int i = 0; i < num; ++i) {
printf(" {@} \n");
printf(" | \n");
printf(" \\|/ \n");
printf(" | \n");
}
};
roseBlock(2);
- 有返回值,有形参
int (^sumBlock) (int, int);
sumBlock =^(int value1, int value2){
return value1 + value2;
};
NSLog(@"sum = %i", sumBlock(10, 40));
block和typedef
// 注意: 利用typedef给block起别名, 和指向函数的指针一样, block变量的名称就是别名
typedef int (^calculteBlock)(int , int);
calculteBlock sumBlock = ^(int value1, int value2){
return value1 + value2;
};
NSLog(@"sum = %i", sumBlock(20, 10));
block用做参数
void goToWork(void (^workBlock)())
{
NSLog(@"起床");
NSLog(@"穿衣服");
NSLog(@"洗漱");
NSLog(@"喝早茶");
NSLog(@"驾车去上班");
// 不一样
// 调用传递的block参数
workBlock();
NSLog(@"收拾东西");
NSLog(@"驾车回家");
NSLog(@"吃晚饭");
NSLog(@"洗澡");
NSLog(@"睡觉");
}
void goToWorkInDay1()
{
//调用goToWork函数,传递block参数值
goToWork(^{
NSLog(@"认识新同事");
});
}
int main(int argc, const char * argv[]) {
goToWorkInDay1();
return 0;
}
Block注意事项
-
没有访问外部变量是全局block,存储代码区
访问外部变量,block copy,存储堆区
-
在block内部可以访问block外部的变量
-
block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部
-
默认情况下, Block内部不能修改外面的局部变量
Block内部可以修改使用__block修饰的局部变量
如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中,block中的变量和外界的变量并不是同一个变量。因为block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值
-
如果没有添加__block是值传递
-
如果加上__block之后就是地址传递,
-
__block int b = 5;
void (^myBlock)() = ^{
b = 20;
NSLog(@"b = %i", b);
};
myBlock();
//输出结果: 20