鏈?zhǔn)骄幊毯秃瘮?shù)式編程

  • 先來看一段代碼:
    Person *person1 = [[Person alloc] init];
    [person1 run1];
    [person1 eat1];

這段代碼說明:定義了一個(gè)Person類,提供了一個(gè)run方法和一個(gè)eat方法
方法聲明:

- (void)run1;
- (void)eat1;

方法實(shí)現(xiàn):

- (void)run1{
    NSLog(@"跑步1");
}
- (void)eat1{
    NSLog(@"吃飯1");
}

這種方式正是我們開發(fā)中最常使用的方式,缺點(diǎn):
1.方法需要單獨(dú)調(diào)用
2.不能隨意組合順序

  • 接下來再來看一段代碼:
    UIView *view = [[UIView alloc] init];
    [self.view addSubview:view];
    
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.mas_equalTo(self.view).mas_offset(0);
        make.top.mas_equalTo(self.view).mas_offset(80);
        make.height.mas_equalTo(100);
    }];

這里使用了Masonry對控件進(jìn)行布局,OC中的對象調(diào)用方法時(shí)的格式一般為:
[對象 對象方法:參數(shù)1,參數(shù)2]
而Masonry約束的這段代碼中,使用了()的方式設(shè)置參數(shù),使用.的方式同時(shí)調(diào)用多個(gè)方法

Masonry中正是使用了函數(shù)式編程與鏈?zhǔn)骄幊痰姆绞?/p>

__函數(shù)式編程特點(diǎn): __使用 "()" 替代OC中的 "[]"

鏈?zhǔn)骄幊痰奶攸c(diǎn):一行代碼一級一級的調(diào)用方法

除了Masonry,另一款開源自動布局框架PureLayout中,也正是使用了這種編程方式,讓代碼閑的更精練易懂

  • 實(shí)現(xiàn)鏈?zhǔn)骄幊?/h5>

如果實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用呢? 首先從代碼入手分析:

目標(biāo):   [[person eat1]run1];
                ↓
                ↓
        Person *person = [person eat1]; 
        [[person eat1] run1];

由此可見,只需要讓每個(gè)方法都有個(gè)instancetype的返回值即可
接下來就模仿這種編程方式,將run和eat方法進(jìn)行改進(jìn)

方法聲明:

- (Person *)run2;
- (Person *)eat2;

方法實(shí)現(xiàn):

- (Person *)run2{
    NSLog(@"跑步2");
    return self;
}
- (Person *)eat2{
    NSLog(@"跑步2");
    return self;
}

這樣再來調(diào)用看一下效果

    Person *person2 = [[Person alloc] init];
    [[[[person2 run2] eat2] run2] eat2];

目前來,鏈?zhǔn)骄幊陶{(diào)用的方式是暫時(shí)實(shí)現(xiàn)了

  • 實(shí)現(xiàn)函數(shù)式編程

如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用呢?首先需要思考,如何調(diào)用函數(shù)時(shí)使用小括號,OC中常用到小括號的場景有哪些? --> block

     // block聲明
     void (^Myblock)() = ^{
        NSLog(@"block");
     }
     // block調(diào)用
     Myblock();

所以第一步,將方法返回值類型改為一個(gè)void(^)()類型

方法聲明:

- (void (^)())run3;
- (void (^)())eat3;

方法實(shí)現(xiàn):

- (void (^)())run3{
    
    void (^MyBlock)() = ^{
        NSLog(@"跑步3");
    };
    
    return MyBlock;
}
- (void (^)())eat3{
    
    // 在run3的基礎(chǔ)上,將block的定義和返回合并
    return ^{
        NSLog(@"吃飯3");
    };
}

調(diào)用效果:

    Person *person3 = [[Person alloc] init];
    person3.eat3();
    person3.run3();

目前來看調(diào)用方法時(shí)使用小括號的效果實(shí)現(xiàn)了,如何結(jié)合鏈?zhǔn)秸{(diào)用呢?

結(jié)合實(shí)現(xiàn)鏈?zhǔn)骄幊痰姆椒?我們現(xiàn)在返回值類型是一個(gè)無參無返回值類型的block,如果讓block的返回值類型為instanceType是不是就可以了呢?

繼續(xù)改動代碼

方法聲明:

- (Person * (^)())run4;
- (Person * (^)())eat4;

方法實(shí)現(xiàn):

- (Person * (^)())run4{

    Person * (^MyBlock)() = ^{
        
        NSLog(@"跑步4");
        return self;
    };
    
    return MyBlock;
}
- (Person * (^)())eat4{
    
    return ^{
        NSLog(@"吃飯4");
        return self;
    };
}

再來看一下調(diào)用效果:

    Person *person4 = [[Person alloc] init];
    person4.eat4().eat4().run4().eat4();

這樣就實(shí)現(xiàn)了函數(shù)式編程和鏈?zhǔn)骄幊?/p>

接下來,如果需要傳遞參數(shù),相信大家也就都會了,只需要設(shè)置Block參數(shù)即可

Person類示例代碼
.h:

#import <Foundation/Foundation.h>

@interface Person : NSObject

#pragma mark -- 最常見的寫法
- (void)run1;
- (void)eat1;

#pragma mark -- 鏈?zhǔn)骄幊?- (Person *)run2;
- (Person *)eat2;

#pragma mark -- 函數(shù)式編程步驟1 -> 調(diào)用方法使用小括號
- (void (^)())run3;
- (void (^)())eat3;

#pragma mark -- 函數(shù)式編程步驟2 --> 鏈?zhǔn)秸{(diào)用多個(gè)方法
- (Person * (^)())run4;
- (Person * (^)())eat4;

#pragma mark -- 函數(shù)式編程步驟3 --> 傳遞參數(shù)
- (Person * (^)(double distance))run5;
- (Person * (^)(NSString *kindOfFood))eat5;

@end

.m:

#import "Person.h"

@implementation Person

#pragma mark -- 最常見的寫法
- (void)run1{
    NSLog(@"跑步1");
}
- (void)eat1{
    NSLog(@"吃飯1");
}

#pragma mark -- 鏈?zhǔn)骄幊?- (Person *)run2{
    NSLog(@"跑步2");
    return self;
}
- (Person *)eat2{
    NSLog(@"跑步2");
    return self;
}

#pragma mark -- 函數(shù)式編程 1
- (void (^)())run3{
    
    void (^MyBlock)() = ^{
        NSLog(@"跑步3");
    };
    
    return MyBlock;
}
- (void (^)())eat3{
    
    // 在run3的基礎(chǔ)上,將block的定義和返回合并
    return ^{
        NSLog(@"吃飯3");
    };
}

#pragma mark -- 函數(shù)式編程 2
- (Person * (^)())run4{

    Person * (^MyBlock)() = ^{
        
        NSLog(@"跑步4");
        return self;
    };
    
    return MyBlock;
}
- (Person * (^)())eat4{
    
    return ^{
        NSLog(@"吃飯4");
        return self;
    };
}

#pragma mark -- 函數(shù)式編程 3
- (Person *(^)(double))run5{
    return ^(double distance){
        NSLog(@"跑了%.2f米",distance);
        return self;
    };
}
- (Person *(^)(NSString *))eat5{
    return ^(NSString *kindOfFood){
        NSLog(@"吃了%@",kindOfFood);
        return self;
    };
}

@end

使用函數(shù)式編程和鏈?zhǔn)骄幊虒τ诜庋b框架和閱讀第三方開源框架有很大幫助
代碼連接:https://github.com/ShenYj/-

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容