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 [email protected]"王五";
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中使用场景

(1)遍历数组或者字典

(2)视图动画

(3)排序

(4)通知

(5)错误处理

(6)多线程等等...

时间: 12-17

OC之Block的使用的相关文章

李洪强iOS开发之OC语言BLOCK和协议

OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么? 苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相似性: (1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. 标识符 ^ (二)基本使用 (1)定义BLOCK变量 Int (^SumBlock)(int,int);//有参数,返回值类型为int Void (^MyBlock)()://无参数,返回值类型为空 (2)利用block封装代

(Object-C)学习笔记(五) --OC的Block

OC的Block 文大大的Block见解 http://www.cnblogs.com/wendingding/p/3709604.html Block跟方法差不多,随写随用,而且做完运算后能即时返回一个返回值,非常方便,大大提高了编程效率.但是不建议多用,因为Block会导致代码的易读性大大降低.

OC语言Block

OC语言Block 一.Block (一)简介  Block是什么?苹果推荐的比较特殊的数据类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. Block和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. Block的应用:(1)动画(2)多线程(3)集合遍历(4)网络请求回调 标识符 ^ (二)基本使用 (1)定义Block变量 Int (^SumBlock)(int,int);//有参数,返回值类型为int Void 

OC语言BLOCK和协议

一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. 标识符 ^ (二)基本使用 (1)定义BLOCK变量 int (^SumBlock)(int, int); // 有参数,返回值类型为int void (^MyBlock)():// 无参数,返回值类型为空 (2)利用block封装代码 (3)Block访

iOS开发——语法OC篇&amp;Block回顾

Block回顾 这里知识简单介绍一下关于Block的语法,如果你觉得这里很简单或者想学习更深入的的使用清查看记者之前写的使用block传值和高级Block使用: http://www.cnblogs.com/iCocos/p/4534281.html http://www.cnblogs.com/iCocos/p/4550169.html http://www.cnblogs.com/iCocos/p/4659878.html http://www.cnblogs.com/iCocos/p/46

OC 06 Block、数组高级

主要内容: ?.Block语法 ?.Block使? 三.Block实现数组排序 Block简介 Block:块语法,本质上是匿名函数(没有名称的函数) 标准C?面没有Block,C语?言的后期扩展版本,加?了匿名函数. C++.JS.Swift等语?,有类似语法,叫做闭包. Block语法和函数指针很相似. 回顾函数指针 函数指针(变量):存放函数地址(函数名)的指针变量. int (*p)(int x,int y) = sum; 函数指针类型:int (*)(int x,int y) 即:指向

swift中闭包 OC中Block 解决循环引用

OC 中 全局宏定义 #define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self; 用法如下: WS(weakself) [self.tableView addHeaderWithCallback:^{ [weakself requestMemberList]; }]; swift 在比闭包 中使用 weakSelf weak var weakSelf = self demo4 {     // 使用?的好处 就是一旦 self 被释

OC基础:block.字面量

block 块语法,能够用block去保存一段代码,或者封装一段代码. block 实际是由c语言实现的,运行效率非常高. block 实际借鉴了函数指针的语法. block (^)(參数类型1 參数名1,參数类型2 參数名2...); 返回值类型  (^)(); 1.没有參数,括号也不能省略 2.參数名能够省略 void(^myBlock1)();   无參数无返回值 void(^myBlock2)(int a,int b);   有參数无返回值 int(^myBlock3)();    无參

OC中 block 的用法

block 常用于反向传值 声明 返回值类型 (^block)(参数列表) 调用 闭包的名字=^(参数列表){}: 闭包的名字(): 如: void(^aaaaa)(int num,NSString *Sring); aaaaa=^(int num,NSString *string){ NSLog(@"%d,%@",num,string); }; aaaaa(120,@“www"); block实现反向传值 (1)用属性实现: 1.在.h文件声明:@property(nona