OC中的函数式编程&链式编程

作者: 优米诺 | 来源:发表于2016-10-26 14:39 被阅读233次

在正常的开发中我们用到的第三方框架就有一个很好的体现了函数式编程和链式编程----Masonry。
例如:
Masonry 经典的代表

[v mas_makeConstraints:^(MASConstraintMaker *make) {
    // 1. 函数式编程:
    // equalTo(self.view)
    // offset(40)
    // 2. 链式编程
    // equalTo(self.view).offset(40)
    make.top.equalTo(self.view).offset(40);
    make.size.mas_offset(CGSizeMake(100, 100));
    make.centerX.equalTo(self.view).offset(-40);
}];

现在我们自己尝试来做函数式编程,新建一个Person类,在Person头文件声明并实现两个方法:

@interface Person : NSObject
- (void)run;
- (void)eat;
@end
#import "Person.h"

@implementation Person
- (void)run {
    NSLog(@"%s", __FUNCTION__);
}

- (void)eat {
    NSLog(@"%s", __FUNCTION__);
}
@end

在ViewController中调用Person中的两个方法:

 Person *person = [Person new];
    
    // 1> run 和 eat 需要单独调用!
    // 2> 不能随意组合顺序!
    [person run];
    [person eat];

这是传统的写法,run和eat只能单独去调用,并不能去组合调用,现在我们来定一个目标1:链式编程

// 目标1:链式编程
// 这是我们想要实现的目标,方法可以自由组合
[[person run] eat ];
[[person eat] run ];
// 解决办法:在[person run] 方法后返回一个person对象,用person对象去调用person内的方法,即:
// 实现如下效果
id obj = [person run1];
    [obj eat1];

obj其实就是一个person对象,用person对象调用person内的方法必然没有问题,有了这个目标之后我们现在开始改造代码:

@interface Person : NSObject
- (void)run;
- (void)eat;

- (Person *)run1;
- (Person *)eat1;
@end

@implementation Person

- (Person *)run1 {
    NSLog(@"%s", __FUNCTION__);
    return self;
}

- (Person *)eat1 {
    NSLog(@"%s", __FUNCTION__);
    return self;
}

在person类内新增加run1方法和eat1方法

id obj = [person run1];
    [obj eat1];
    
    id obj2 = [person eat1];
    [obj2 run1];
    
    NSLog(@"---");
    [[person run1] eat1];

以上代码输出为:

Snip20161026_6.png

可以看到我们实现了我们的目标1:链式编程,但是还没有实现函数式编程,现在我们定义目标2:函数式编程

// 目标2:函数式编程
// 函数式编程的特点是用 '()'去调用方法,那么在OC中我们在什么时候回用到 '()'调用方法呢
// 相信很多人第一个想到的应该就是Block
/**
 person.run2().eat2();
 person.eat2().run2();
以上两行代码是我们现在需要实现的目标
*/

接着到Person类内改造代码:

@interface Person : NSObject
- (void)run;
- (void)eat;

- (Person *)run1;
- (Person *)eat1;

// 关于链式编程和函数式编程
// 如果要实现函数式编程,需要返回 `block`
- (Person * (^)())run2;
- (Person * (^)())eat2;
@end

@implementation Person
- (Person * (^)())run2 {
    
    Person * (^runBlock)() = ^ {
        NSLog(@"run2");
        
        return self;
    };
    
    return runBlock;
}

- (Person *(^)())eat2 {
    
    return ^ {
        NSLog(@"eat2");
        
        return self;
    };
}
@end

在ViewController内实现方法调用:

//  目标2: 函数式编程!
//    person.run2().eat2();
//    person.eat2().run2();
    // 需求 :person.run2() => person.eat2();
    person.run2().run2().eat2().run2();

输出如下:

Snip20161026_7.png

我们看到现在已经实现了函数式编程。但是还有一个问题,在Masonry中()执行方法时是带有参数的,我们继续来改造代码:

// 在block中是可以带参数的,所以现在对代码进行如下改动
@interface Person : NSObject
- (void)run;
- (void)eat;

- (Person *)run1;
- (Person *)eat1;

// 关于链式编程和函数式编程
// 如果要实现函数式编程,需要返回 `block`
- (Person * (^)())run2;
- (Person * (^)())eat2;

// 返回的 block 可以接参数
- (Person * (^)(NSString *food))eat3;
- (Person * (^)(double distance))run3;
@end

@implementation Person
- (Person *(^)(NSString *))eat3 {
    
    return ^ (NSString *food) {
        NSLog(@"吃 %@", food);
        
        return self;
    };
}

- (Person *(^)(double))run3 {
    
    return  ^ (double distance) {
      
        NSLog(@"跑 %f", distance);
        
        return self;
    };
}

@end

继续回到ViewController内调用方法:

//  目标2: 函数式编程!
//    person.run2().eat2();
//    person.eat2().run2();
    // 需求 :person.run2() => person.eat2();
    person.run2().run2().eat2().run2();

    NSLog(@"---");
    person.run3(1000).eat3(@"water").run3(1000).eat3(@"water");

现在看输出:

Snip20161026_9.png

到目前为止我们已经实现了链式编程和函数式编程。感谢刀哥,有刀哥的分享才有的这篇文章。

相关文章

  • OC中的函数式编程&链式编程

    在正常的开发中我们用到的第三方框架就有一个很好的体现了函数式编程和链式编程----Masonry。例如:Mason...

  • iOS-链式编程

    函数式编程------->链式编程 函数式编程: 调用方式 我们最终目的是将函数式编程转换为链式编程:首先将调用方...

  • iOS 函数编程 & 链式编程

    函数式(链式)编程 函数式编程概念 函数式编程是种编程范式 函数式编程 Functional Programmin...

  • ReactiveObjC入门

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

  • iOS链式编程及函数式编程

    提到链式编程和函数式编程,最典型的代表是Masonry 比较完美的实现了函数式编程和链式编程。例如 ``` [vi...

  • 工作iOS技术总结

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

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

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

  • Scala面试题

    scala语言的特点: 集成了面向对象和函数式编程 函数式编程是将计算机的运算视为函数运算 链式编程 Scala中...

  • OC中链式编程和函数式编程

    最近看到了链式编程和函数式编程这两个概念,这两天不是那么的忙 所以也研究了下这两个概念;在查询链式编程和函数式编程...

  • 链式编程与函数编程

    1. 链式编程 2. 函数式编程 例子:

网友评论

  • Noah1985:为什么总是将链式和函数式混着来说呢?
  • 柯柯格格:这不是完全是刀哥的讲解么???
    H_Cynic:或许你看过所谓的刀哥 别人没看过 lz现在不就是在给没看过的人讲解么 我对你的质疑表示质疑
  • 冰三尺:有一点我不明白, - (Person * (^)(double distance))run3; 为什么调用的时候可以写成person.run3(1000), run3的方法并没有参数, double distance是返回值, 不清楚这个返回值和参数到底是什么关系?
    双手插兜Jeff:person.run3 相当于[person run3]。[person run3]的返回值是Person * (^)(double distance)这个 block。(1000)相当于是给这个 block 赋值。

本文标题:OC中的函数式编程&链式编程

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