Block
一、Block的基本定义
Block的基本写法(也是详细写法):
returnType (^blockName)(params) = ^returnType(params) { // code... };
中文再解释:返回类型 (^Block的名字)(Block的参数) = ^返回类型(Block的参数) { 这里放代码 },例:
int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){ return 100; };
如果你的Block不需要返回类型和参数,那么你可以简写为:
void (^myBlock2)() = ^(){ };
或
void (^myBlock2)(void) = ^void(void){ };
返回类型或参数,没有的话可以用“void”代替。
你也可以把等于号右边,^后的()删除,即是:
void (^myBlock2)() = ^{ };
这样是不是很简洁?
你也可以先定义一个Block函数,但不写函数的实现,我们可以在后面再写具体函数的实现,像这样:
void (^myBlock2)(void); myBlock2 = ^{ };
二、Block作为方法定义
把Block定义在方法里,与上面不同的是,Block的名字不需要在声明时写上,而是在后面,像这样:
- (void)getWtihBlock:(void (^)())block { // code... // 记得要调用block block(); }
使用方法:
[self getWtihBlock:^{ NSLog(@"sdf"); }];
下面作了一个详细点的例子,并写了备注:
/** * 追加自身字符串N次(每次复制前加一个换行\n) * * @param string 字符串 * @param count 追加次数 * @param stringBlock 目标Block,其中str参数为结果字符串 */ // Block也可以定义在方法里,但是不需要定义Block的名字 // IOS开发很多的API也用到了Block,像UIView的块动画 - (void)getStrWithString:(NSString *)string CopyCount:(int)count resultString:(void (^)(NSString *str))stringBlock { NSMutableString *newString = [NSMutableString stringWithString:string]; for (NSUInteger i = 0; i < count; i++) { NSUInteger len = [string length]; NSString *insertString = [NSString stringWithFormat:@"\n%@", string]; [newString insertString:insertString atIndex:len]; } // 调用block,传入字符串newString stringBlock(newString); }
用法也是一样:
BlockObject *block = [[BlockObject alloc] init]; [block getStrWithString:@"Garvey" CopyCount:3 resultString:^(NSString *str) { // str为处理后的结果 NSLog(@"str is %@", str); }];
有时候复杂的Block语法会令到函数的声明难以阅读,所以会经常使用typedef对Block起一个新类型。
typedef void (^ResultBlock)(NSString *str);
定义方法时就变成了:
- (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock;
让我们对比一下,使用typedef前后:
// 使用前 - (void)getStrWithString:(NSString *)string CopyCount:(int)count resultString:(void (^)(NSString *str))stringBlock; // 使用后 - (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock;
注意:使用方法是一样的,只不过定义变得简单了。
Block基础部分
1.Block的声明
Block的定义和函数的声明差不多,就是把函数名改成(^blockName)即可。下面是block声明的代码。
有返回值的
1
|
int (^sumBlock) ( int , int ); |
无返回值的
1
|
void (^myBlock)( int , int ); |
2.给block块赋值
给声明好的block,赋值。block的值就是个函数体,给block块赋值有两种方式,一个在声明的时候赋值,一个是先声明在赋值。
先声明再赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//代码块的声明 void (^myBlock)( int , int ); //给代码块赋值 myBlock = ^( int a, int b) { //test ++; //报错 NSLog(@ "main_test = %d" , test); //blockVar++不报错; blockVar ++; NSLog(@ "blockVar = %d" , blockVar); int sum = a + b; NSLog(@ "a + b = %d" , sum); }; |
在声明的时候赋值
1
2
3
4
5
|
int (^sumBlock) ( int , int ) = ^( int a, int b) { int sum = a + b; return sum; }; |
3.调用block
block的使用和普通函数的使用相同,调用方法如下:
1
2
|
//调用代码块并接收返回值 int sum = sumBlock(20, 30); |
4.把block当做参数传入函数
1
2
3
4
5
6
|
//把代码块作为函数参数 void blockFunction( int (^myBlock)( int , int )) { int sum = myBlock(10,20); NSLog(@ "fun_sum = %d" , sum); } |
5.在代码块中使用局部变量和全局变量
在block中可以和对全局变量进行访问和修改,但对局部变量只可以访问,若想修改的话,我们可以在声明局部变量的时候加上关键字__block
代码如下:
1
|
__block int blockVar = 0; |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 在 VS Code 中,一键安装 MCP Server!
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 千万级大表的优化技巧