- 先來看一段代碼:
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/-