Objective-C之Block基本应用
前言:本文整理了一些block的一些基础用法以及对使用场景的一些理解,如果有哪里不对,欢迎留言讨论哦~
本质
block又称之为代码段,是一个可以存储代码的数据类型。
block基本使用
// 语法
// 返回值类型 (^block变量名称)(参数列表);
// 栗子1:一个无返回值,无参数的block
void (^myBlock)();
// 栗子2:有返回值,无参数的block
int (^myBlock)();
// 栗子3:有返回值,有参数的block
int (^myBlock)(int num1,int num2);
block的简写
1.如果写的代码段没有返回值,那么代码段的返回值可以省略
注意:是代码段的返回值,而不是声明block的返回值
// ✅ 正确形式
//省略前
void (^myBlock)(int num) = ^void(int num){
......
};
//省略后
void (^myBlock)(int num) = ^(int num){
......
};
// ❎ 错误形式
(^myBlock)(int num) = ^void(int num){
......
};
2.如果写的代码段没有参数,那么代码段的小括号可以省略
注意:是代码段的小括号,而不是声明block的小括号
// ✅正确形式
// 省略前
int (^myBlock)() = ^int(){
......
};
// 省略后
int (^myBlock)() = ^int{
......
};
// ❎错误形式
int (^myBlock) = ^int(){
......
};
3.结合1、2
既没有返回值,也没有参数的block,则可以将返回值与参数列表的小括号全部省略掉
// 省略前
void (^myBlock)() = ^void(){
......
};
// 省略后
void (^myBlock)() = ^{
......
};
4.声明block变量的时候,如果有指定参数,可以只写参数的类型而不写参数的名称
注意:这里说的是声明,而不是代码段
// 省略前
int (^myBlock)(int num) = ^int(int num) {
......
};
// 省略后
int (^myBlock)(int) = ^int(int num) {
......
};
5.block的返回值
无论代码段是否有返回值,在写代码段的时候都可以省略,系统会自动的确认返回值的类型。
如果代码段中没有返回任何数据,系统会认为这个代码段没有返回值
如果代码中有返回数据,返回的数据是什么类型,那么系统会认为这个代码段的返回值就是什类型
// 举个栗子,下面的代码块返回值类型为int
int (^myBlock)() = ^ {
return 1;
};
6.建议
虽然简写可以少些一写代码,但是在多人协同开发时,还是建议完整的定义一个block,有利于提高代码的可阅读性。
typedef定义block
// 语法
//typedef 返回值类型 (^block名称)(参数列表);
// 举个栗子
typedef int (^myBlock)(int num1, int num2);
block访问外部变量
1.在block内部可以读取定义在外部的变量的值,包括外部的局部变量和全局变量。
2.在block内部可以修改定义在外部全局变量的值,但是不可以修改定义在外部的局部变量。
3.如果想在在block内部修改定义在外部的局部变量,需要在外部变量的定义前加上关键字__block。
int num1 = 100; // 全局变量
typedef void (^myBlock)();
int main() {
int num2 = 200;
__block int num3 = 300;
myBlock blockTest = ^void() {
// 读取
NSLog(@"%d",num1); // 打印100
NSLog(@"%d",num2); // 打印200
NSLog(@"%d",num3); // 打印300
// 修改
num1++; // num1 = 101
//num2++; // 解开注释会报错
num3++; // num3 = 301
NSLog(@"%d",num1); // 打印101
NSLog(@"%d",num3); // 打印301
};
}
block作为方法参数
block作为函数参数的直观作用:被调用的方法可以按照调用者的意愿完成某些逻辑
举个栗子:
现在有一个数组@[@Korean,@“China”,@“America”],需要排序。小红:我想按照首字母升序排序
小明:我想按照每个元素的长度升序排序
这时我们就可以实现一个方法,参数为不同的排序规则
// 用于存储排序方法的代码段
typedef NSArray*(^sortBlock)(NSArray *);
int main(){
// 字符串数组
NSArray *arr = @[@"Korean",@"China",@"America"];
// 小红的方法
sortBlock xiaohongBlock = ^NSArray*(NSArray *){
return @[@"America",@"China",@"Korean"];
};
// 小明的方法
sortBlock xiaomingBlock = ^NSArray*(NSArray *){
return @[@"China",@"Korean",@"America"];
};
return 0;
}
// 排序方法
- (void)showWithArr:(NSArray *)arr withMySortBlock:(sortBlock) myBlock{
NSInteger nLen = [arr count];
NSArray *afterSortArr = myBlock(arr);
for (int i = 0; i < nLen ;i++) {
NSLog(@"%@",afterSortArr[i]);
}
}
输出结果:
小红:
America
China
Korean
小明:
China
Korean
America
注:为方便理解,上述代码中并没有写具体的算法,而是直接将排序好的数组返回。
block作为方法返回值
int main(){
void(^myBlock)(void) = [self show];
myBlock();
return 0;
}
-(void(^)(void))show{
return ^void(){
NSLog(@"block 作为函数返回值");
};
}