Block
简述:block 与 函数类似。同时可以直接用作回调。
一般当做函数使用
- 实际使用,感觉比较少,一般用在回调,代替delegate,少些很多代码,同时会带来一些奇怪的问题。注意循环引用等一些block 的疑难杂症。
// block 返回 *(^block 函数名)(参数类型) = ^(参数名){ return }
NSString *(^testBlock)(NSString *) = ^(NSString *name){
return [NSString stringWithFormat:@"我的名字是:%@",name];
};
NSString *testString = testBlock(@"张三");
NSLog(@"%@",testString);
作为回调 代替delegate
使用 button 点击时间回调举例
- 1 定义 block 回调函数
// 简单实现 view 上有2个button,点击时间回调,一个 ok 一个 cancel
typedef NS_ENUM(NSUInteger, selectButton) {
selectButtonOK,
selectButtonCancle
};
// 定义 block
typedef void(^selectButtonBlock)(selectButton buttonIndex);
@interface BlockView : UIView
// 回调方法
-(void)setSelectBolck:(selectButtonBlock )block;
// ******** eg ******** //
// 为了 更简化上面的 代码,可以更直接,直接使用copy 的block ,供外部调用,type 类型直接用path传,注意不是很安全。这个不详细介绍。
@property (nonatomic, copy) void(^myBlock)(NSInteger path);
- 2 创建 2个button 连接点击事件
UIButton *okButton = [UIButton buttonWithType:UIButtonTypeSystem];
okButton.frame = CGRectMake(0, 0, 100, 100);
[okButton addTarget:self action:@selector(okButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:okButton];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
cancelButton.frame = CGRectMake(0, 100, 100, 100);
[cancelButton addTarget:self action:@selector(cancelButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:cancelButton];
- 3 使用block 链接button 点击事件
// 需要一个 全局 block,将外部穿进来的 block赋值
static selectButtonBlock TempBlock;
-(void)setSelectBolck:(selectButtonBlock)block{
if (block) {
TempBlock = block;
}
}
-(void)okButtonAction{
if (TempBlock) {
TempBlock(selectButtonOK);
}
}
-(void)cancelButtonAction{
if (TempBlock) {
TempBlock(selectButtonCancle);
}
}
- 4 外部使用 举例
BlockView *testView = [[BlockView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
// block button 点击事件 回调
[testView setSelectBolck:^(selectButton buttonIndex) {
if (buttonIndex == selectButtonOK) {
NSLog(@"ok");// 对应 点击 ok button
} else if (buttonIndex == selectButtonCancel){
NSLog(@"cancel");//对应 点击 cancel button
} else {
NSLog(@"其他 error");
}
}];
类似AFN 判断 回调,或者 错误回调
- 1 简单 举例 2 个数相加 是否大于100,大于100返回较大的值,不大于100返回较小的值。
+(void)addBackInt1:(NSInteger)int1 int2:(NSInteger)int2 success:(void (^)(NSInteger max))success failure:(void (^)(NSInteger min))failure;
+(void)addBackInt1:(NSInteger)int1 int2:(NSInteger)int2 success:(void (^)(NSInteger))success failure:(void (^)(NSInteger))failure{
if (int1 + int2 > 100) {
if (success) {
success(int1 > int2 ?int1:int2);
}
}else{
if (failure) {
failure(int1 > int2 ?int2:int1);
}
}
}
- 2 外部使用 判断回调
[blockView addBackInt1:14 int2:80 success:^(NSInteger max) {
NSLog(@"%zi",max);
} failure:^(NSInteger min) {
NSLog(@"%zi",min);
}];
关于 block 使用需要注意的 一些问题
- 循环引用
- block 对局部变量只读