美文网首页
Block的使用,快跟我一起学起来吧

Block的使用,快跟我一起学起来吧

作者: 小屋新 | 来源:发表于2017-07-06 17:57 被阅读18次

block,本人之前很少用这个,传值什么的都是用代理,所以对这个不太重视,后来见了一位大牛写的代码中几乎都是block函数,看起来简洁,使用起来又方便,所以,今天稍微整理了一下,没有太深入,仅限于使用。

Block的作用主要有三种:

1、做为函数参数

2、反向传值

3、循环引用

现在,切入正题,block的简单使用

首先,我们来定义一个简单的block

int (^FirstBlock)(int a, int b) = ^(int a, int b){
        return a+b;
    };
    
    NSLog(@"%d",FirstBlock(10,20)) ;

解析一下,看下图(好像有点乱)

2E9740D6-8ED7-48A8-B316-A8B2995A1000.png

通常其他的block都是在这个基础上变形的,可以有返回参数,可以没有返回参数,可以传参,也可以不传参,如下:

void (^FirstBlock)(int a, int b) = ^(int a, int b){
        //Do Something
    };//没有返回值
    
int (^FirstBlock)() = ^(){
        return 10;
    };//不能传参数
    
    NSLog(@"%d",FirstBlock()) ;

这些都是简单一些的使用,下面讲解一下怎么在两个控制器之间进行回调,我们有两个控制器,一个是ViewController,一个是NextViewController,我们在NextViewController.h中定义一个block,在NextViewController.m中实现

#import <UIKit/UIKit.h>

@interface NextViewController : UIViewController

typedef void(^ChangeColor)(UIColor *color);

@property (nonatomic, strong) ChangeColor changeColor;

@end
#import "NextViewController.h"

@interface NextViewController ()

@end

@implementation NextViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 110, 100, 50)];
    btn.backgroundColor = [UIColor redColor];
    [self.view addSubview:btn];
    [btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
}

- (void)btnClicked{
    self.changeColor([UIColor redColor]);
    [self.navigationController popViewControllerAnimated:YES];
}

我们在ViewController中使用

#import "ViewController.h"

#import "NextViewController.h"
@interface ViewController ()



@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(0, 100, 100, 50);
    btn.backgroundColor = [UIColor grayColor];
    [self.view addSubview:btn];
    [btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)btnClicked{
    NextViewController *nextVC = [[NextViewController alloc] init];
    __weak typeof(self) weakSelf = self;
    nextVC.changeColor = ^(UIColor *color) {
        weakSelf.view.backgroundColor = color;
    };
    [self.navigationController pushViewController:nextVC animated:YES];
}

这样就简单实现了一个界面颜色更改的回调,感觉使用block比代理要方便一些。


最近在封装MJRefresh,又发现了一个实用block的好处,比方说,我们只是需要记录一个状态,然后我们就可以直接在方法中直接定义一个空的block,然后在需要的地方使用就可以了,也不需要使用typedef提前定义,示例:

- (void) startRefreshWithUITableView:(UIScrollView *)scrollView andHeader:(void(^)())header;//(void(^)())这里就是一个最简单的block

实现方法:

MJRefreshGifHeaderRewrite *mj_header = [MJRefreshGifHeaderRewrite headerWithRefreshingBlock:^{
        header();//这里存储了 headerWithRefreshingBlock:这个block的执行状态
    }];

在其他类中的使用:

[self startRefreshWithUITableView:self.tableview andHeader:^{
        //do something
        //  和MJ Refresh中headerWithRefreshingBlock:使用相同
    }];

这是我在封装MJRefresh的DIY时用到的方法,需要MJRefresh Demo的可以去这个地方下载看一下:
https://github.com/houcj/CJ_MJRefresh


我们在封装网络请求的时候也经常会使用block进行传值,基本逻辑和我上面写的回调基本是一样的,这里就不再赘述了,有什么问题,可以留个言,帮助到你记得喜欢呦。


小知识:我们有时候需要在block块里面修改属性值,但是我们直接修改是会报错的,如下:


59062D65-7053-4910-8F47-8E9295C19968.png

但是有时候,我们还是需要在block中修改数据的,这要怎么办呢?不要着急,有一个修饰叫__block ,当我们需要修改某个对象的时候,可以在前面作下修饰,如下:

7C91DF7E-552B-4EBE-8B55-062D2C77E626.png

搞定,perfect!

相关文章

网友评论

      本文标题:Block的使用,快跟我一起学起来吧

      本文链接:https://www.haomeiwen.com/subject/awihhxtx.html