Blocks 是一个带有自动变量值的匿名函数
1 block语法
完整形式的block语法与一般c语言函数定义,有两点不同
(1)没有函数名
(2)带有 "^"
c:
int func(int a)
{
return a;
}
block:
^int (int a)
{
return a;
}
block语法的BN范式: ^返回类型 参数列表 表达式 ^ int (int count){...};
可以省略为 ^ 参数列表 表达式^ (int count){...};
如果没有参数可以省略为 ^ 表达式^ {...};
2 block类型变量
c语言中函数指针表达方式:
int func(int count)
{...}
int (*funcptr)(int count);
block语法将"*" 换为 "^"
int (^blk)(int) = ^ (int count){...};
int (^)(int)为block类型 blk为变量名
赋值操作
int (^blk1)(int) = blk 将blk赋值给新变量blk1
为了方便记述可以用c中方法typedef来解决该问题
typedef int (^blt_t)(int); 定义了一个block类型
blt_t myBlock = ^(int count){...};
int (^myBlock)(int) = ^(int count){...};
blt_t myBlock; => int (^myBlock)(int) ;
以上2个表达式是等价的.
注意:typedef int (^blt_t)(int); 和 int (^blt_t)(int); 不一样前者是一个类型,后者是一个类型变量要区分
当用于函数参数的时候可以以下方式:
1 -(void)setCallBack:(void (^)(int data)) block
2 typedef int (^blt_t)(int);
-(void)setCallBack:(blt_t) block
3 截获自动变量
前面介绍了匿名函数,这节介绍什么是带有自动变量值。
在block表达式中截获所有的自动变量的值,即保存该自动变量的瞬间值,即使改写block中使用的自动变量也不会影响block执行时自动变量的值。
int n = 10;
void (^testBlock)() = ^()
{
NSLog(@"block :%d", n);
};
n = 20;
testBlock(n);
这里block截获了n得瞬间值10,虽然在调用block之前修改了n的值,但是打印出来的还是10.
__block 说明符
想在block表达式中修改block以外的自动变量,需要在该自动变量前面加上__block说明符
__block int n = 10;
void (^testBlock)() = ^()
{
NSLog(@"block :%d", n);
};
n = 20;
testBlock(n); 打印出来20.
4 OC对象瞬间值
int val = 0;
void (^blk)(void) = ^{val = 1;}; 如果在block中修改自动变量会产生编译错误。
那如果用oc对象呢?
id array = [[NSArray alloc]init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc]init];
[array addObject:obj];
}
这是没问题的,但是如果你要修改自动变量array的值也会产生编译错误。这个有点像c语言中将一个const指针当参数传到函数中,虽然不能修改指针的值但是可以修改指针指向的值。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· 为什么AI教师难以实现
· AI Agent爆火后,MCP协议为什么如此重要!
· Draw.io:你可能不知道的「白嫖级」图表绘制神器
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势