美文网首页
IOS开发之block回调及链式编码原理

IOS开发之block回调及链式编码原理

作者: 有心向往 | 来源:发表于2016-11-20 20:11 被阅读50次

    随着学习的深入,对block的认识也是越来越清晰,就是”一个可以截获自动变量的匿名函数“,在一般应用上比较顺手,但是在底层的转化上面还在学习中,这里不涉及,只是如标题写的应用方面的写法及中间遇到的问题。

    我们先说一下block的回调

    现在有这样一个需求,一个人(称为A)想剪发,让理发师(称为B)帮助他剪发,剪发过程B决定。
    A.h文件
    #import <Foundation/Foundation.h>
    @interface PeopleA : NSObject
    -(void)doSometing:(void(^)())someOne;
    @end
    
    A.m文件
    #import "PeopleA.h"
    
    @implementation PeopleA
    -(void)doSometing:(void (^)())someOne{
        NSLog(@"A去理发");
        if (someOne){
            NSLog(@"找到了理发师");
            someOne();
            NSLog(@"理发师给我剪完头发了");
        }else{
            NSLog(@"没有找到理发师");
        }
    }
    @end
    
    
    B.h文件
    @interface PeopleB : NSObject
    -(void)doWork;
    @end
    
    B.m文件
    #import "PeopleB.h"
    #import "PeopleA.h"
    @implementation PeopleB
    -(void)doWork{
        PeopleA* p = [PeopleA new];
        [p doSometing:^{
            NSLog(@"我现在给A剪发,我给他这样这样剪");
            
        }];
    
    }
    @end
    
    主调函数.m文件部分代码
        PeopleB* p = [PeopleB new];
        [p doWork];
    
    

    下面是输出结果

    # A去理发
    # 找到了理发师
    # 我现在给A剪发,我给他这样这样剪
    # 理发师给我剪完头发了
    
    1.要注意定义block的语法,定义的block可以有返回值,可以有参数,例如:-(void)doMethod:(int(^)(CGFloat numb, UIImage* image)) block;就是定义了一个没有返回值的,参数为返回值为int类型的block函数,并且block含有numb和image两个参数。
    2.注意,在block调用的时候,看看block是否存在,有可能没有实现代码,用if (block)去判断,存在再去调用,不然会出错。
    3.block匿名函数可以做任何变量,可以做函数参数,做属性,做返回值等。

    --

    现在我们说一下用block实现链式编码

    关于链式编码,最常见的就是Masonry第三方库,写约束真是方便。

    [button mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.mas_equalTo(0);
            make.top.mas_equalTo(40);
            make.width.mas_equalTo(100);
        }];
    

    在OC语言中,点语法,其实就是调用属性的set和get方法;我们可以直接设置为属性,也可以直接设置get方法,属性系统自动就给添加了。
    下面我就写一个在网上最常见的案例,加减乘除计算的链式代码

    Calculator.h文件
    
    @interface Calculator : NSObject
    @property(nonatomic)float result;
    -(Calculator*(^)(float))add;
    -(Calculator*(^)(float))sub;
    -(Calculator*(^)(float))div;
    -(Calculator*(^)(float))multi;
    @end
    Calculator.m文件
    
    #import "Calculator.h"
    
    @implementation Calculator
    -(instancetype)init{
        if (self = [super init]) {
            self.result = 0;
        }
        return self;
    }
    -(Calculator*(^)(float))add{
        return ^Calculator*(float num){
            _result += num;
            return self;
        };
    }
    -(Calculator*(^)(float))sub{
        return ^Calculator*(float num){
            _result -= num;
            return self;
        };
    }
    -(Calculator*(^)(float))div{
        return ^Calculator*(float num){
            if (num == 0){
                NSAssert(num != 0, @"是0,不可以做被除数");
            }
            _result = _result / num;
            return self;
        };
    }
    -(Calculator*(^)(float))multi{
        return ^Calculator*(float num){
            _result = _result * num;
            return self;
        };
    }
    @end
    
    主调函数的调用部分代码
    Calculator* cal = [Calculator new];
        cal.add(1).add(12).sub(1).div(1).multi(10);
        NSLog(@"%f",cal.result);
    
    
    
    

    调用的结果为

    # 120.000000
    
    这段链式代码,主要是说明首先是用()调用,需要返回block,接着.链式调用,在返回block调用后需要返回自己(self)
    有时候在Masonry看到and,with关键子,其实就是一个block什么都不做,直接返回自己(self)即如下:
    -(Calculator*(^)())and{
        return ^Calculator*(){
            return self;
        };
    }
    -(Calculator*(^)())with{
        return ^Calculator*(){
            return self;
        };
    }
      //代码链加上上述代码,对代码结果没有影响
    

    上面就是今天分享的内容,代码测试没有问题,大概做法和思路就是这样,又发现问题可以在下面反馈,谢谢!

    相关文章

      网友评论

          本文标题:IOS开发之block回调及链式编码原理

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