iOS 包看包会的链式编程

作者: Codepgq | 来源:发表于2017-07-08 14:50 被阅读546次

<br />
......此处省略10000字,作为一个程序员,代码才是文字,是的,开撸。

<br />

1 一步一步来:创建一个对象,并且创建两个方法 eat 和 run

声明方法 实现方法

现在我们可以这样子调用方法

 Result * res = [[Result alloc] init];
 [res eat];
 [res run];

<br />

2 如何实现把eatrun写在一行上

[[res eat2] run2];

分析一下,对象方法是由对象调用,当我们调用eat2之后在调用run2方法,run2是对象方法,只有对象调用,那是不是我在调用eat2方法之后返回调用对象就可以了?

声明方法 实现方法

<br />

  • 效果图


    效果图

<br />

  • 果不其然,这样子就可以做到了,但是有现在有一个问题啊,调用eat方法,到底吃啥我不知道,我也决定不了。我想决定自己吃啥,不能老是让你决定是吧。

<br />
于是我们就可以这样子:吃啥,跑多远外界决定

声明方法 实现方法

现在我们就要完成这样子的效果了

[[[res eat3:@"apple"] eat3:@"banana"] run3:100.0];
  • 效果图


    效果

<br />

下面我们看看block的写法

我们想类似于Masonry那样子去调用怎么写呢?
先来完成一个eat4run4

#pragma mark - 点语法
- (void(^)())eat4;
- (void(^)())run4;

实现

- (void(^)())eat4{
    void(^eat4Block)() = ^(void){
        NSLog(@"eat4");
    };
    return eat4Block;
}
- (void(^)())run4{
    
    return ^(void){
        NSLog(@"run4");
    };
}
  • 分析
ok,看我们这里做了什么,首先我们定义了一个有返回值的方法,返回值是一个没有返回值,没有参数的block,
然后我们在实现文件里面用两种方式去返回了这个block。
然后们就可以在外界这样子调用了
res.eat4();
res.run4();

为什么可以这样调用呢?

  • 分析
block的写法
void (^a)() = ^{
   NSLog(@"调用了block");
};
a();
从上面的代码可以看得出来,调用a()的时候就会执行block里面的代码,在上面我们定义的方法返回一个block
我们可以这样子写:
void (^x)() = [res eat4];
x();
效果是一样的,
.eat4调动的就是get方法,然后我们拿到了一个block,
这个时候我么你直接(),就相当于上面的两步,所以我们可以这样子调用

<br />
然后我们发现,还是不可以链式啊,还是要写两行的,根据上面所述的对象方法的理念,我们可以这样子。

#pragma mark - 点语法 链式 不带参数
- (Result*(^)())eat5;
- (Result*(^)())run5;

实现文件

- (Result*(^)())eat5{
    
    Result *(^eat5Block)() = ^{
        NSLog(@"eat5");
        return self;
    };
    
    return eat5Block;
}
- (Result*(^)())run5{
    return  ^{
        NSLog(@"run 5");
        return self;
    };
}

上面的代码也是两种方式去实现,但是看最后的代码就可以发现,把self 返回出去了,即是当前的对象返回出去了,所以我们就可以这样子写了

res.eat5().eat4();

<br />

  • ok,经过上面的代码之后,这个时候还是只能调用吃和跑,不能自己想吃什么就吃什么,想跑多远就跑多远,于是参照对象方法的写法,我们就可以这样子.
#pragma mark - 点语法 链式 带参数
- (Result*(^)(NSString * food))eat6;
- (Result*(^)(float metter))run6;

实现

- (Result*(^)(NSString * food))eat6{
    Result *(^eat6Block)(NSString * food) = ^(NSString * food){
        NSLog(@"eat6 %@",food);
        return self;
    };
    return eat6Block;
}
- (Result*(^)(float metter))run6{
    return ^(float metter){
        NSLog(@"run6 %.2f",metter);
        return self;
    };
}

<br />

  • ok 到这里,我们就不在 吃 和 跑 了

<br >

没错,我们换成了 jumpplay ,来接着看看链式

首先还是一样实现最基本的用法
在项目中,下面的方法我们经常会用

#pragma mark - 普通对象方法 - 外界处理 不带参数
- (void)jump:(void(^)())block;
- (void)play:(void(^)())block;

#pragma mark - 普通对象方法 - 外界处理 带参数
- (void)jump2:(void(^)(float metter))block;
- (void)play2:(void(^)(NSString *string))block;

实现

- (void)jump:(void(^)())block{
    if (block) {
        block();
    }
}

- (void)play:(void(^)())block{
    if (block) {
        block();
    }
}

- (void)jump2:(void(^)(float metter))block{
    if (block) {
        block(100);
    }
}
- (void)play2:(void(^)(NSString *string))block{
    if (block) {
        block(@"basketball");
    }
}

调用如下:

 [res jump:^{
     NSLog(@"我来控制输出什么");
 }];
 [res play:^{
     NSLog(@"我来决定玩什么");
 }];
 [res jump2:^(float metter) {
     NSLog(@"被控制要跳%.2f米",metter);
 }];
 [res play2:^(NSString *string) {
     NSLog(@"被要求玩%@",string);
 }];

<br />

上面两种调用方式是不是很常见啊,然后我们结合两种方式一起,再结合链式来玩玩吧。

先来试试没有参数

定义

实现

实现
  • 效果图
类是这样子

<br />

带参数

<br />

定义

实现

实现

调用

调用

<br />

上面看了那么久的普通调用方式,现在我们来玩玩block的形式的

首先定义方法

#pragma mark - 点语法 - 传入参数,内部自己处理,返回参数,自己决定做什么
-(void(^)(float metter, void(^)(float metter)))jum5;
-(void(^)(NSString* str, void(^)(NSString* str)))play5;

实现方法

-(void(^)(float metter, void(^)(float metter)))jum5{
    void (^jum5Block)(float metter, void(^)(float metter)) = ^(float metter, void(^neibuBlock)(float metter)){
        if (neibuBlock) {
            neibuBlock(metter);
        }
    };
    return jum5Block;
}
-(void(^)(NSString* str, void(^)(NSString* str)))play5{
    return ^(NSString* str, void(^neibuBlock)(NSString* str)){
        if (neibuBlock) {
            neibuBlock(str);
        }
    };
}

但是我们调用得这个样子调用

res.jum5(123,^(float metter){
    NSLog(@"我自己决定我跳%.2f米",metter);
});
res.play5(@"我给你100块",^(NSString * str){
    NSLog(@"%@,你给我一个篮球",str);
});

效果图

<br />
上面的调用方式明显不爽嘛,换成链式的,其实就是返回一个有返回值且返回值是调用的block
定义

#pragma mark - 点语法 - 传入参数,内部自己处理,返回参数,自己决定做什么 链式
-(Result*(^)(float metter, void(^)(float metter)))jum6;
-(Result*(^)(NSString* str, void(^)(NSString* str)))play6;

实现

-(Result*(^)(float metter, void(^)(float metter)))jum6{
    Result* (^jum6Block)(float metter, void(^)(float metter)) = ^(float metter, void(^neibuBlock)(float metter)){
        if (neibuBlock) {
            neibuBlock(metter * 1.2);
        }
        
        return self;
    };
    return jum6Block;
}
-(Result*(^)(NSString* str, void(^)(NSString* str)))play6{
    return ^(NSString * str, void(^neibuBlock)(NSString * str)){
        
        if (neibuBlock) {
            neibuBlock([NSString stringWithFormat:@"加一个漂亮的签名 %@",str]);
        }
        
        return self;
    };
}

效果图

效果图

到这里为止,了解阶段就完成了,下面要开始实现了一个有用的东西了。

首先我们如果实现一个弹窗,带确定、取消按钮,同时可以输入账户、密码,还不包括处理文字输入情况,我们就需要写这么多代码

UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"牛逼" message:@"💯就是这么强" preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction * action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"点击了取消");
    }];
    [alert addAction:action1];
    UIAlertAction * action2 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"点击了确定");
    }];
    [alert addAction:action2];
    
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        
    }];
    
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        
    }];
    
    [self presentViewController:alert animated:YES completion:nil];
    

<br />

但是如果我们用链式编程,可以做到实时监听输入情况,外界控制是否密文显示,并且扩张性很强。

PQAlertController *alert= [PQAlertController alertControllerWithTitle:@"难道我这么帅" message:@"帅,不存在的!" preferredStyle:UIAlertControllerStyleAlert];
alert.addAction(@"取消",^{
        NSLog(@"cancel");
    }).addAction(@"确定",^{
        NSLog(@"ok");
    }).addTextInput(@"请输入账户",NO,^(NSString *text,UITextField *textField){
        NSLog(@"%@",text);
    }).addTextInput(@"请输入密码",YES,^(NSString *text,UITextField *textField){
        NSLog(@"%@",text);
    });
[self presentViewController:alert animated:YES completion:nil];
实现类似RAC的text_signal

感谢ZAQ大神带入门


简单的介绍一下PQAlertcontroller吧
1 同时支持iphone ,ipad
2 支持链式调用
3 可以实时监听textField输入回调

alertController.gif

Demo 附上

用star、喜欢砸死我

相关文章

  • iOS 包看包会的链式编程

    ......此处省略10000字,作为一个程序员,代码才是文字,是的,开撸。 1 一步一步来:创建一个对象,并且创...

  • iOS-链式编程思想

    在iOS中,链式编程虽然用的不太多,但是,在特定的应用环境下,利用block实现链式编程的话,会大大的提高编程效率...

  • iOS链式编程

    在iOS中,链式编程虽然用的不太多,但是,在特定的应用环境下,利用block实现链式编程的话,会大大的提高编程效率...

  • 工作iOS技术总结

    链式编程、函数式、面向接口编程思想 iOS 之ReactiveCocoa 链式编程2 WKWebView的缓存处理...

  • ReactiveObjC入门

    ReactiveObjC基础用法 iOS开发三种编程方式(响应式编程、函数编程、链式编程),函数编程最常用,链式编...

  • 链式编程总结

    链式编程总结 @(iOS) 研究了一下链式编程,但是感觉项目中用处不是很多。 介绍 1.什么时候使用链式编程?在面...

  • ios开发中的包的处理

    IOS 详解socket编程[oc]粘包、半包处理 在做socket编程时,如果是做tcp连接,那就不可避免的会遇...

  • iOS 链式编程简单的使用

    iOS 链式编程简单的使用 链式编程-顾名思义,链式,连贯性为其主要特征,放在编程领域来讲,说简单点就是把一系列的...

  • R语言学习笔记(14)-常用包

    reshape包;tidyr,dplyr包;链式操作符%>% 参考:https://www.bilibili.co...

  • iOS链式、函数式和响应式编程

    原文编程思想-iOS链式、函数式和响应式编程 在了解链式、函数式和响应式编程前,我们需要回顾下Block,它在下面...

网友评论

  • 伦敦乡下的小作家:大佬,学习完了你的demo,想了解下,实际开发中,在什么情景下用链式的比较多
    Codepgq:@伦敦乡下的小作家 我也是半吊子...
    伦敦乡下的小作家:@Codepgq 老哥稳哦,近期打算好好读一读你的RAC文章,虽然之前用过,但不是很扎实
    Codepgq:@伦敦乡下的小作家 比如那个alert controller的时候,看心情吧:joy::joy::joy:
  • 有趣程序猿:思路很清晰,值得借鉴
    Codepgq:@China最小的奋斗者 谢谢
  • iCode_:如果你打印运行时间,block的链式会多耗时差不多一半的时间,所以在需要频繁调用的地方不建议用这种方式。
    Codepgq:我不知道你所指的是哪个代码,然后我就就测试了一下我demo中封装的alertController这个,分别用两种方式进行调用,得到两组测试数据(每个测试5次,测试开始时间是创建之前,测试结束时间是显示之后,计算两者的时间差 使用的是这个方法获取时间CFAbsoluteTimeGetCurrent(),使用机器6p,测试方式:编译到手机,每次打开点击显示)
    非block链式
    0.017218
    0.021022
    0.019553
    0.018715
    0.016700
    block链式
    0.018646
    0.016878
    0.018261
    0.017682
    0.014913
  • 化二缺:已经 star
    Codepgq:@飞镖有毒 多谢兄台
  • 雪_晟:可以的啊 感觉链式很简洁
    Codepgq:是的呢

本文标题:iOS 包看包会的链式编程

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