一、前言
block是iOS4.0+和Mac oxX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性。所谓匿名函数,也成闭包函数,即允许创建一个临时的没有指定名称的函数。最经常作回调函数(callback)参数的值,也有其他用法,比如作为一个变量值来使用。
二、基础知识
1、再iOS中,使用脱字符”^”来声明一个block变量,block的内容包含在{}中,并且和C语言一样用“;”来表示语句的结束。具体定义如下图:
如果没有参数则参数名num可以省略。
2、定义一个简单的没有返回值,没有参数的block,如下:
1
2
3
4
5
6
7
8
9
|
- (
void
)viewDidLoad {
[
super
viewDidLoad];
//block
void
(^myBlock)(
void
) = ^(
void
) {
NSLog
(@
"This is a block without parameter and returned value"
);
};
myBlock();
}
|
也可以直接写成:
1
2
3
4
5
6
7
8
9
|
- (
void
)viewDidLoad {
[
super
viewDidLoad];
//block
void
(^myBlock)(
void
) = ^ {
NSLog
(@
"This is a block without parameter and returned value"
);
};
myBlock();
}
|
3、定义一个简单的有参数没有返回值的block,如下:
//有参数,没有返回值的block
1
2
3
4
5
6
7
|
-(
void
)blockWithParameterButNoReturnData
{
void
(^myBlock)(
int
) = ^(
int
num) {
NSLog
(@
"%d"
,num*100);
};
myBlock(4);
}
|
4、定义一个有参数,有返回值得block,如下:
//有参数,有返回值的block
1
2
3
4
5
6
7
8
|
-(
void
)blockWithParameterAndReturnValue
{
int
(^myBlock)(
int
) = ^(
int
num) {
return
num * 100;
};
int
result = myBlock(2);
NSLog
(@
"This is a block with parameter and return value :%d"
,result);
}
|
5、现在分析一下block的存储域:
运行下面函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
-(
void
)testBlock
{
void
(^blockOne)(
void
) = ^ {
NSLog
(@
"This is block one"
);
};
int
c = 10;
void
(^blockTwo)(
void
) =^(
void
) {
NSLog
(@
"This is a block two %d"
,c);
};
void
(^blockThree)(
void
) =[blockTwo
copy
];
NSLog
(@
"blockOne address is :%@"
,blockOne);
NSLog
(@
"blockTwo address is :%@"
,blockTwo);
NSLog
(@
"blockThree address is :%@"
,blockThree);
}
|
运行结果如下:
结果是:
blockOne因为没有使用任何外部变量,他的存储区域在全局区,而blockTwo因为使用了外部变量,则存储在堆。而两个内存地址一样,都位于堆内存中。
另附:
Block再内存中的位置分为三种类型:NSGlobalBlock、NSStackBlock、NSMallocBlock
其中:NSGlobalBlock:类似函数,位于text段
NSStackBlock:位于栈内存,函数返回后Block将无效
NSMallocBlock:位于堆内存。
注:参考网上某个大神的写的。