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

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

我们先说一下block的回调

现在有这样一个需求,一个人(称为A)想剪发,让理发师(称为B)帮助他剪发,剪发过程B决定。
A.h文件
#import 
@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回调及链式编码原理)