Block

来源:互联网 发布:淘宝茶叶有多少人竞争 编辑:程序博客网 时间:2024/05/16 14:51
一.Block定义1.1定义

(1)Block是OC中的一种数据类型,在iOS开发中被广泛使用

(2)^是Block的特有标记

(3)Block的实现代码包含在{}之间

(4)大多情况下,以内联inline函数的方式被定义和使用

(5)Block与C语言的函数指针有些相似,但使用起来更加灵活
1.2示例代码
?
1
2
3
4
5
6
void(^demoBlock)() =^ {
   NSLog(@"demo");
};
int(^addBlock)(int,int) =^(intx, int y) {
   returnx +y;
};
说明:(1)(返回类型)(^块名称)(参数类型)=^(参数列表){代码实现};(2)如果没有参数,等号后面参数列表的()可以省略


.Block使用

2.1 Block被当做参数直接传递
?
1
2
3
4
5
6
7
<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的方式
?
1
2
3
4
5
6
7
8
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同样可以使用在定义之前声明的局部变量
?
1
2
3
4
5
6
7
8
<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中是只读的!
?
1
2
3
4
5
6
7
<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关键字!
?
1
2
3
4
5
6
7
<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的类型,便于在后续直接使用
?
1
2
3
4
5
6
7
8
9
<span style="font-size:18px;">typedefdouble(^MyBlock)(double,double);
MyBlock area = ^(doublex, double y) {
    returnx * y;
};
MyBlock sum = ^(doublea, double b) {
    returna + 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当做比较特殊的对象
?
1
2
3
4
5
6
7
8
9
10
11
12
13
<span style="font-size:18px;">#pragma mark 定义并添加到数组
@property (nonatomic, strong) NSMutableArray *myBlocks;
int(^sum)(int,int) =^(intx, int y) {
   return[self sum:x y:y];
};
[self.myBlocks addObject:sum];
int(^area)(int,int) =^(intx, 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循环引用问题
直接上代码:
?
1
2
3
4
5
6
7
8
9
10
11
@property(nonatomic, strong) NSMutableArray *myBlocks;
#pragma mark 将代码改为调用self的方法
int(^sum)(int,int) = ^(intx, 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)对象被添加到数组中,会被数组强引用

\


<喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+zsrM4r3ivvY6PC9wPgo8cD6+1rK/seTBv8SsyM+2vMrHx7/S/dPDtcSjrMDrv6rG5Mv51Nq1xNf308PT8tauuvO+zbvhsbvKzbfFLMq508NfX3dlYWu52Lz819ajrL/J0tS9q77Wsr+x5MG/yfnD986qyPXS/dPDPC9wPgo8cD48cHJlIGNsYXNzPQ=="brush:java;">__weak DemoObj *weakSelf =self;

在Block中引用weakSelf,则Block不会再对self做强引用
?
1
2
3
int(^sum)(int,int) = ^(intx, int y) {
        return[weakSelf sum:x y:y];
    };


2.7 Block在iOS中使用场景

(1)遍历数组或者字典
(2)视图动画
(3)排序
(4)通知
(5)错误处理

(6)多线程等等...


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 刚开的新店没人怎么办 淘宝访客量突然下降怎么办 支付宝账号封了怎么办 苹果x手机黑屏打不开怎么办 淘宝支付密码被锁定怎么办 淘宝支付密码锁定了怎么办 很抱歉手机淘宝停止运行怎么办 苹果手机桌面淘宝图标不见了怎么办 提示网页上有错误怎么办 淘宝定制家具违约两个月怎么办 同行在买家评价下面评论怎么办 淘宝知识产权侵权被投诉了怎么办 闲鱼买家说是假货退货怎么办 日验证失败次数上限怎么办 淘宝卖家发货不全怎么办 子账号登录不上怎么办 淘宝宝贝曝光量少怎么办 淘宝买东西退款卖家拒绝怎么办 华为手机淘宝不能收藏宝贝怎么办 包裹发出不想要了怎么办 淘宝改登录密码忘记了怎么办 三星s8应用闪退怎么办 淘宝购物商家不发货怎么办 淘宝商家迟迟不发货怎么办 买家地址写错了怎么办 买家写错快递地址怎么办 淘宝退款选择服务类型出不来怎么办 网购东西发错了怎么办 拒签商家不退款怎么办 红米手机无响应怎么办 淘宝网登录密码忘记了怎么办 淘宝网密码忘记了怎么办 京东抢购不发货怎么办 微商不想做了怎么办 减肥过程中饿了怎么办 滴滴车龄超过6年怎么办 网络公选课没过怎么办 大学网络课挂了怎么办 淘宝虚拟订单买家恶意退款怎么办 淘宝卖家虚拟发货怎么办 淘宝买虚拟产品被骗了怎么办