1.Block的基本用法
(1)无返回值,无形参
// void代表block将来保存的代码没有返回值
// ()代表block将来保存的代码没有形参
// (^roseBlock) 代表reseBlock是一个block变量, 可以用于保存一段block代码
void (^roseBlock) ();
// 如果block没有参数, 那么^后面的()可以省略
roseBlock = ^(){
printf(" {@} \n");
printf(" | \n");
printf(" \\|/ \n");
printf(" | \n");
};
// 要想执行block保存的代码, 必须调用block才会执行
roseBlock();
(2)无返回值,有形参
void (^roseBlock) (int);
roseBlock = ^(int num){
for (int i = 0; i < num; ++i) {
printf(" {@} \n");
printf(" | \n");
printf(" \\|/ \n");
printf(" | \n");
}
};
roseBlock(2);
(3)有返回值,有形参
int (^sumBlock) (int, int);
sumBlock =^(int value1, int value2){
return value1 + value2;
};
NSLog(@"sum = %i", sumBlock(10, 40));
2.利用typedef给block起别名
// 在函数外面定义
typedef int (^calculteBlock)(int , int);
calculteBlock sumBlock = ^(int value1, int value2){
return value1 + value2;
};
NSLog(@"sum = %i", sumBlock(20, 10));
calculteBlock minusBlock = ^(int value1, int value2){
return value1 - value2;
};
3.Block的注意事项
(1)block中可以访问外面的变量
int a = 10;
void (^myBlock)() = ^{
NSLog(@"a = %i", a);
};
myBlock();
(2)block中可以定义和外界同名的变量, 并且如果在block中定义了和外界同名的变量, 在block中访问的是block中的变量
int a = 10;
void (^myBlock)() = ^{
int a = 20;
NSLog(@"a = %i", a);
};
myBlock();
(3)默认情况下, 不可以在block中修改外界变量的值
如果没有添加__block是值传递,如果加上__block之后就是地址传递, 所以可以在block中修改外界变量的值
// 因为block中的变量和外界的变量并不是同一个变量
// 如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中
// 因为block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值
int a = 10;
NSLog(@"&a = %p", &a);
void (^myBlock)() = ^{
a = 50;
NSLog(@"&a = %p", &a);
NSLog(@"a = %i", a);
};
a = 20;
myBlock();
// 如果想在block中修改外界变量的值, 必须在外界变量前面加上__block
// 如果在block中修改了外界变量的值, 会影响到外界变量的值
__block int a = 10;
NSLog(@"&a = %p", &a);
void (^myBlock)() = ^{
a = 50;
NSLog(@"&a = %p", &a);
NSLog(@"a = %i", a);
};
myBlock();
NSLog(@"a = %i", a);
4.通过block逆向传值
逆传:用block来传值,处理网络的时候经常使用block封装代码。
请求网络数据(延迟) 先把展示到控件的代码先保存到block,等请求到数据的时候直接调用Block
A文件(用来保存block代码):
addVc.block = ^(XMGContact *contact){
// 1.联系人添加到数组
[self.contacts addObject:contact];
// 2.刷新表格
[self.tableView reloadData];
};
B文件(逆传):
.h文件
// 利用block传值,需要把什么传递出去,就作为block参数,通常不需要返回值
typedef void(^XMGAddViewControllerBlock)(XMGContact *contact);
@property (nonatomic, strong) XMGAddViewControllerBlock block;
.m文件
// 0.把文本框的值包装成联系人模型
XMGContact *c = [XMGContact contactWithName:_nameField.text phone:_phoneField.text];
// 1.把联系人添加到联系人控制器的数组,让联系人控制器刷新表格
if (_block) {
_block(c);
}
// 2.回到联系人控制器
[self.navigationController popViewControllerAnimated:YES];