Block简析

block是iOS开发中用起来非常简便好用的一种回调结构体。它又叫闭包、代码块、语法块,它比Delegate那种代理函数式回调方便很多。

‘^’是block特有的符号。

block可以带传入参数,也可以带传出参数。
示例:

1
2
3
int (^myBlock)(int,int) = ^(int num,int num2){
return num*num2;
};

如上一个简单的block。(^myBlock)表示这个block名是’myBlock’;返回类型在开头定义了为’int’;传参在block名后面定义了,是’(int,int)’,即传入两个int参数;等号后面就是实现逻辑了,’^(int num,int num2)’定义了传参名为num、num2;大括号内包含实现了逻辑,返回num*num2。

block可以先定义后实现,也可以定义实现一起,区别在于作用域的不同。

在函数内部定义并实现的block有点类似于java的匿名内部类,这种block也只能作用于当前函数。
示例:

1
2
3
4
5
6
-(void)testBlock{
void (^blockTest)(int) = ^(int num){
NSLog(@"num:%d",num);
};
blockTest(2);
}

可以通过typedef在头文件先定义block,然后再其他地方实现。

这种block作用域广泛,不仅本类内的函数都可调用,其他类通过引入头文件也可调用。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//.h文件
#import <Foundation/Foundation.h>;
//block定义
typedef void (^BlockTest)(int);

@interface TUBlockOperate : NSObject
//block类成员
@property (nonatomic,assign) BlockTest blockTest;

+ (TUBlockOperate *)sharedInstance;

-(void)printTest;

@end

-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//.m文件
#import "TUBlockOperate.h"

@implementation TUBlockOperate

+ (TUBlockOperate *)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&amp;pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}

-(void)printTest{
//该block的实现也可以在其他类
//block实现
_blockTest = ^(int num){
NSLog(@"num:%d",num);
};

//block调用
_blockTest(22);
}

@end

  • 变量修饰符__block:

在block的逻辑体(大括号里面),调用逻辑体外面的变量,只能read不能write。可以用__block修饰符来修饰该变量,这样在block逻辑体内就能read&write了。

  • 关于循环引用:

某对象有一个Block属性,然而这个Block属性中又引用了对象的其他成员变量,那么就会对这个变量本身产生强应用,造成该对象跟Block都不能释放,那么变量本身和他自己的Block属性就形成了循环引用。

  • 解决循环引用:

循环引用的原因在于两个对象都进行了强引用保存计数。解决的方法是把一个对象改为弱引用不保存计数。可以这样实现:

1
__block typeof(self) weakSelf = self;

———-Just Over