美文网首页
iOS之block的使用

iOS之block的使用

作者: 长不大的帅小伙 | 来源:发表于2016-09-30 19:12 被阅读81次

这篇文章主要的目的是介绍一下block如何使用,希望对大家有所帮助,同时也方便自己记忆。

block基础知识

1. 下面通过实例由浅入深逐步分析:
  • 例1:
    一个最简单的block如下:
^{ 
   // block implementation here
}
  • 例2:
    从下面这个例子看出block其实就是一个值,可以把他当成int,float,或者OC对象,赋值给变量。只不过这个变量看起来有点奇怪。
void (^blockName)() = ^{ // block implementation here};
  • 例3:
    这个例子中定义的block返回值是int,参数是a和b。
int (^addBlock)(int a, int b) = ^{ 
    return a + b;
};
int add = addBlock(2, 5); // add == 7
  • 例4:
    block有个强大之处:在声明它的范围里,所有变量都可以为其所捕获,也就是说那个范围里的全部变量,在block中依然可用
int c = 5;
// __block int c = 5; // 加__block修饰,在下面的块中才可以修改c的值,否则只能访问不能修改
int (^addBlock)(int a, int b) = ^{ 
    // c = 3;  
    return a + b + c; // 依然可以访问c
};
int add = addBlock(2, 5);
2. block闭包写法

如果你有过类似js、lua等脚本语言的编程经验,那么你应该对闭包这个概念比较熟悉,IOS中的block就可以实现闭包,使代码结构更巧妙灵活。

- (void)functionAA {
    int a = 10;
    if (flag) {
        NSLog(@"do some thing1 with a %@", @(a));
        NSLog(@"do some thing2 with a %@", @(a));
    } else {
        if (flag1) {
            NSLog(@"do some thing1 with a %@", @(a));
            NSLog(@"do some thing2 with a %@", @(a));
        } else {
            NSLog(@"do some thing3");
        }      
    }
}

通过上面这段代码不难看出flag和flag1中要做的事其实是一样的,然而有什么办法能让他们复用起来,使代码结构更简洁,相信很多人想到可单独抽一个私有方法出来,这的确是一个办法,不过这样有个麻烦的事,需要把参数传递到私有方法,下面对这段方法进行改造:

- (void)functionAA {
    int a = 10;
    void (^doSomeThingBlock)() = ^{
        NSLog(@"do some thing1 with a %@", @(a));
        NSLog(@"do some thing2 with a %@", @(a));
    };
    if (flag) {
        doSomeThingBlock();
    } else {
        if (flag1) {
            doSomeThingBlock();
        } else {
            NSLog(@"do some thing3");
        }      
    }
}

对比这两段代码,这里的doSomeThingBlock就是闭包的写法,而且doSomeThingBlock可以访问到变量a,如果使用抽出私有方法的方式就需要把变量a传给私有方法。

3. 如何为常用的块类型创建typedef

先看一个例子:

// 原来的写法
int (^JLSomeBlock)(BOOL flag, int value) = ^{};

// 新写法
typedef int (^JLSomeBlock)(BOOL flag, int value);
JLSomeBlock block = ^(BOOL flag, int value){};

对于一些常用的block,我们可以用typedef定义,下面再举个例子进行分析:

- (void)doFuncWithCallBackBlock:(void (^)(int a, int b))block;

// 采用声明block的方式
typedef void(^callBackBlock)(int a, int b);
- (void)doFuncWithCallBackBlock:(callBackBlock)block;

设想一下,当有特殊要求要给doFuncWithCallBackBlock方法的block参数加一个参数NSData,如果采用的是第一种方式,这个时候就痛苦了,需要在项目中全局去查收所有doFuncWithCallBackBlock,然后进行逐个修改,那么如果用的是第二种方式,只需要将声明部分修改成typedef void(^callBackBlock)(int a, int b, NSData *data);就搞定了。具体用哪种方式,做项目的时候多考虑考虑,慢慢就会体会的更深了,从而选择出最佳方案。

4. block和delegate做个简单比较

在IOS开发中,动态代理设计模式无处不在,如:tableView、collectionView等各种控件,苹果都会封装好,并且通过delegate的方式留下开口,让使用者去实现它的delegate中定义的方法,苹果会在它封装的底层代码中去调用我们实现的方法,拓展性极强。block还有个强大的用处,就是他也可以充分的体现这种思想。

  • delegate的方式
/** 代理方式的代码片段 */
- (void)fetchData1 {
    self.fetcher1.delegate = self;
    [self.fetcher1 start]; // 会在start方法中调用代理方法
}
- (void)fetchData2 {
    self.fetcher2.delegate = self;
    [self.fetcher2 start]; // 会在start方法中调用代理方法
}

// 代理方法
- (void)dataFetcher:(JLDataFetcher *)fetcher didFinishWithData:(NSData *data)
{
    if(fetcher == self.fetcher1){
        // do something
        self.data = data;
    } else if(fetcher == self.fetcher2){
        // do something
        self.data = data;
    }
}

从上面代码片段可以看出,一旦情况很多种的时候,代理方法会越来越长,那么如果说采用block的方式会有什么效果呢?请看事例:

  • block方式
- (void)fetchData1 {
    [self.fetcher1 startWithCompletionHandler:^(NSData *data){
        // do something
        self.data = data;
    }];
}
- (void)fetchData2 {
    [self.fetcher2 startWithCompletionHandler:^(NSData *data){
        // do something
        self.data = data;
    }];
}

这里的block会在startWithCompletionHandler方法中被调用,和上面代理的方式会在start方法中调用代理方法是一个道理,这样的好处在于回调的逻辑可以各自分开处理,具体更多的好处还是自己多多体会吧。

相关文章

  • iOS Block存储域及循环引用

    系列文章:iOS Block概念、语法及基本使用iOS Block实现原理iOS Block __block说明符...

  • iOS Block实现原理

    系列文章:iOS Block概念、语法及基本使用iOS Block __block说明符iOS Block存储域及...

  • ios block使用

    iOS Block的使用一 .最简单的block使用******使用block的三个步骤:1.定义block变量 ...

  • iOS Block __block说明符

    系列文章:iOS Block概念、语法及基本使用iOS Block实现原理iOS Block存储域及循环引用 上一...

  • block编程, __block, __weak, __stro

    参考:block编程iOS __weak和__strong在Block中的使用__block & __weak &...

  • Block 初见

    Block 初见 介绍 iOS block 的相关知识 目录 Block 背景知识 Block 使用方式 Bloc...

  • block引用变量造成循环引用解决方案

    参考文章:[ iOS之Block报错:capturing self strongly in this block ...

  • iOS之block的使用

    之前群上一个人问我block怎么用,他说虽然也工作半年多了,但是很少自己用block,我本想百度一个demo给他,...

  • iOS之block的使用

    这篇文章主要的目的是介绍一下block如何使用,希望对大家有所帮助,同时也方便自己记忆。 block基础知识 1....

  • iOS Block实例

    iOS之Block详解:Block详解 ViewController.h(ARC) ViewController....

网友评论

      本文标题:iOS之block的使用

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