学习Block之前,我们先了解下匿名函数和闭包性的概念。
匿名函数实际上是一个没有名字或者标示的函数,匿名函数只有内容,我们可以将其存储在一个变量中,或者将其当做一个参数传递给另一个函数使用。
闭包性是允许一个函数访问其所声明上下文中的变量,甚至是在不同的运行上下文中。
Block的定义:
int (^SumBlock) (int, int) = ^(int a, int b) {
return a + b;
}
该语句定义了一个叫Sum的Block对象,它带有两个int参数,返回int类型,等号右边是Block的具体实现。
还可以用typedef来定义Block的别名:
typedef int (^SumBlock) (int, int) IntSum;
定义一个Block变量:
IntSum intSum = ^(int a, int b) {
return a + b;
}
Block的闭包性:
void test() {
//Block可以访问局部变量,但默认情况下不能修改
int c = 20;
//使用__block修饰的局部变量,可以在Block中修改
__block int d = 30;
IntSum intSum = ^(int a, int b) {
NSLog(@"c = %i", c);
d = 40;
return a + b;
}
NSLog(@"%i", intSum(10, 20));
NSLog(@"d = %i", d);
}
使用Block来实现回调:
定义一个Button类,该类有一个block用来监听按钮被点击;
//Button.h
#import <Foundation/Foundation.h>
@class Button;
typedef void (^ButtonBlock) (Button *btn);
@interface Button : NSObject
@property (nonatomic, assign) ButtonBlock block;
- (void)click;
@end
//Button.m
#import "Button.h"
@implementation Button
- (void)click {
_block(self);
}
@end
//main.m
#import <Foundation/Foundation.h>
#import "Button.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Button *button = [[[Button alloc] init] autorelease];
button.block = ^(Button *btn) {
NSLog(@"按钮%@被点击了", button)
};
[button click];
}
return 0;
}