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 对局部变量只读

其他

待补充
http://www.cocoachina.com/ios/20160224/15349.html