Block即代码块,有点类似函数
效率很高,苹果官方推荐使用。
可以用Block实现类似Java8的新特性 lambda表达式 的效果,也和匿名类很像。有篇博客对block分析很透彻:
http://www.cnblogs.com/ymonke/p/3511304.html
1. 定义一个Block:
形式为:
类型 (^ block名) (参数类型用逗号隔开)= ^(参数类型和参数名) {
具体实现
};
void testBlock1() {
int (^myBlock1) (int, int) = ^(int a, int b) {
return a + b;
};
int s = myBlock1(1, 2);
NSLog(@"s = %i", s);
}
或者可以借助typedef定义:
typedef int (^MyBlock2) (int, int);
void testBlock2() {
MyBlock2 myBlock2 = ^(int a, int b) {
return a * b;
};
int s = myBlock2(2, 3);
NSLog(@"%i", s);
}
2. Block可以访问局部变量,但默认不能修改(编译阶段就会报错);如果要修改,在外部声明的局部变量加关键字__block(两个下划线!)。Java匿名类中要访问外部变量需要在外部变量前加final,并且不能修改。
3. 可以实现Java中接口回调的功能。(参考了M了个J老师的视频)
具体如下:(ARC模式on)
main.m
#import <Foundation/Foundation.h>
#import "Button.h"
typedef int (^MyBlock2) (int, int);
void testBlock2() {
MyBlock2 myBlock2 = ^(int a, int b) {
return a * b;
};
int s = myBlock2(2, 3);
NSLog(@"%i", s);
}
void testBlock1() {
int (^myBlock1) (int, int) = ^(int a, int b) {
return a + b;
};
int s = myBlock1(1, 2);
NSLog(@"s = %i", s);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
// testBlock1();
// testBlock2();
Button *button = [[Button alloc] init];
//设置回调方法。
button.listener = ^(Button *button) {
NSLog(@"%@被点击啦!", button);
};
//模拟点击时间,触发回调。
[button click];
}
return 0;
}
Button.h
#import <Foundation/Foundation.h>
@class Button;
typedef void (^MyListenerBlock) (Button *button);
@interface Button : NSObject
// block 的 setter处理不是assign, 用copy
// 原因: http://www.cnblogs.com/ymonke/p/3511304.html
// 利用Block实现回调
@property (nonatomic, copy) MyListenerBlock listener;
- (void)click;
@end
Button.m:
#import "Button.h"
@implementation Button
- (void)click {
_listener(self);
}
@end