首页 > 代码库 > OC之Block的使用
OC之Block的使用
一.Block定义
1.1定义
(1)Block是OC中的一种数据类型,在iOS开发中被广泛使用(2)^是Block的特有标记(3)Block的实现代码包含在{}之间(4)大多情况下,以内联inline函数的方式被定义和使用(5)Block与C语言的函数指针有些相似,但使用起来更加灵活
1.2示例代码
void(^demoBlock)() =^ { NSLog(@"demo"); }; int(^addBlock)(int, int) =^(int x, int y) { return x +y; };
说明:
(1)(返回类型)(^块名称)(参数类型)=^(参数列表){代码实现};
(2)如果没有参数,等号后面参数列表的()可以省略
二.Block使用
2.1 Block被当做参数直接传递
<span style="font-size:18px;">NSArray *array= @[@"张三",@"李四",@"王五",@"赵六"]; [array enumerateObjectsUsingBlock:^(id obj, NSUIntegeridx, BOOL*stop) { NSLog(@"第 %d 项内容是 %@",(int)idx, obj); if ([@"王五"isEqualToString:obj]) { *stop = YES; } }];</span>
说明:
遍历并NSLog()array中的内容,当obj 为"王五"时停止遍历
2.2 对象传递进Block的方式
NSString *stopName =@"王五"; NSArray *array= @[@"张三",@"李四",@"王五",@"赵六"]; [array enumerateObjectsUsingBlock:^(idobj, NSUInteger idx,BOOL *stop) { NSLog(@"第 %d 项内容是 %@",(int)idx, obj); if ([stopName isEqualToString:obj] || idx == stopIndex) { *stop = YES; } }];
说明:
为保证Block中的代码正常运行,在将stopName的指针传递给Block时,Block会自动对stopName的指针做强引用
2.3 Block使用局部变量
在被当做参数传递时,Block同样可以使用在定义之前声明的局部变量
<span style="font-size:18px;">intstopIndex = 1; NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"]; [arrayenumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"第 %d 项内容是 %@", (int)idx, obj); if ([@"王五" isEqualToString:obj] || idx == stopIndex) { *stop = YES; } }];</span>
注意:
默认情况下,Block外部的变量,在Block中是只读的!
<span style="font-size:18px;">BOOL flag = NO; [arrayenumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if([@"王五" isEqualToString:obj] || idx == stopIndex) { *stop = YES; flag = YES; // 编译错误!!! } }];</span>
如果要修改Block之外的局部变量,需要使用__block关键字!
<span style="font-size:18px;">__block BOOL flag = NO; [arrayenumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if([@"王五" isEqualToString:obj] || idx == stopIndex) { *stop = YES; flag = YES; // 现在可以修改了!!! } }];</span>
无需使用__block关键字,在块代码中可以修改成员变量的数值(比较少用)
2.4 使用typedef定义Block
使用typedef定义一个Block的类型,便于在后续直接使用
<span style="font-size:18px;">typedef double(^MyBlock)(double, double); MyBlock area = ^(double x, double y) { return x * y; }; MyBlock sum = ^(double a, double b) { return a + b; }; NSLog(@"%.2f", area(10.0, 20.0)); NSLog(@"%.2f", sum(10.0, 20.0));</span>
说明:
(1)typedef是关键字用于定义类型,MyBlock是定义的Block类型
(2)area、sum分别是MyBlock类型的两个Block变量
(3)尽管,typedef可以简化Block的定义,但在实际开发中并不会频繁使用typedef关键字这是因为Block具有非常强的灵活性,尤其在以参数传递时,使用Block的目的就是为了立即使用
2.5 添加到数组
Block是一种数据类型,可以将Block当做比较特殊的对象
<span style="font-size:18px;">#pragma mark 定义并添加到数组 @property (nonatomic, strong) NSMutableArray *myBlocks; int(^sum)(int, int) =^(int x, int y) { return [self sum:x y:y]; }; [self.myBlocks addObject:sum]; int(^area)(int, int) =^(int x, int y) { return [self area:x y:y]; }; [self.myBlocks addObject:area]; #pragma mark 调用保存在数组中的Block int(^func)(int, int) = self.myBlocks[index]; return func(x,y);</span>
2.6 Block循环引用问题
直接上代码:
@property(nonatomic, strong) NSMutableArray *myBlocks; #pragma mark 将代码改为调用self的方法 int(^sum)(int, int) = ^(int x, int y) { return [self sum:x y:y]; }; [self.myBlocks addObject:sum]; #pragma mark 对象被释放时自动调用 - (void)dealloc { NSLog(@"DemoObj被释放"); }说明:
上面的代码出现的问题,循环引用的结果就是对象无法被释放!
(1)self对myBlocks的强引用
(2)sum对self的强引用
(3)对象被添加到数组中,会被数组强引用
问题解决:
局部变量默认都是强引用的,离开其所在的作用域之后就会被释放,使用__weak关键字,可以将局部变量声明为弱引用
__weak DemoObj *weakSelf =self;
在Block中引用weakSelf,则Block不会再对self做强引用
int(^sum)(int, int) = ^(int x, int y) { return [weakSelf sum:x y:y]; };
2.7 Block在iOS中使用场景
(2)视图动画
(3)排序
(4)通知
(5)错误处理
(6)多线程等等...
OC之Block的使用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。