在了解鏈?zhǔn)侥淠恕⒑瘮?shù)式和響應(yīng)式編程前,我們需要回顧下Block豌汇,它在下面的編程中起著核心作用幢炸。
Block
block表達(dá)式語法:
^返回值類型(參數(shù)列表){表達(dá)式}
例如:
^int (int count) {
return count + 1;
};
聲明類型變量的語法
返回值類型(^變量名)(參數(shù)列表) = block表達(dá)式
例如:
int (^sum)(int count) = (^int count) {
return count + 1;
};
作為函數(shù)參數(shù)的語法
- (void)func(int (^)(int))block {
}
定義block簡寫
typedef int (^Sumblock)(int);
- (void)func(Sumblock)block {
}
作為返回值的語法,相當(dāng)于get方法,不允許帶參數(shù)
- (int (^)(int))func {
return ^(int count) {
return count ++;
};
}
定義block簡寫
typedef int (^Sumblock)(int);
- (Sumblock)func {
return ^(int count) {
return count ++;
};
}
總結(jié)
- block作為對象的屬性
- block 作為方法的參數(shù)
- block作為返回值>芗M鸹病!(擴(kuò)展性非常強(qiáng)逻澳,今天的主角)
鏈?zhǔn)骄幊?/h4>
鏈?zhǔn)骄幊趟枷胩攸c:方法的返回值必須是方法的調(diào)用者
下面是我們的普通的寫法
@interface Person : NSObject
- (void)eat;
- (void)sleep;
@end
@implementation Person
- (void)eat
{
NSLog(@"%s", __FUNCTION__);
}
- (void)sleep
{
NSLog(@"%s", __FUNCTION__);
}
@end
ViewController.m
Person *person = [[Person alloc] init];
調(diào)用時必須單個調(diào)用闸天,而且不能任意組合順序
/** 普通的調(diào)用方式 */
[person eat];
[person sleep];
鏈?zhǔn)綄懛?方法增加一個返回值,且返回值為調(diào)用者本身
// 鏈?zhǔn)綄懛?Person.h
- (Person *)eat;
- (Person *)sleep;
Person.m
- (Person *)eat
{
NSLog(@"%s", __FUNCTION__);
return self;
}
- (Person *)sleep
{
NSLog(@"%s", __FUNCTION__);
return self;
}
ViewController.m
Person *person = [[Person alloc] init];
/** 鏈?zhǔn)綄懛?這樣不僅可以無限調(diào)用斜做,而且可以控制順序 */
[[person eat] sleep];
[[person sleep] eat];
[[person eat] eat];
/** 通過”點”語法苞氮,將需要執(zhí)行的代碼塊連續(xù)的書寫下去,就是鏈?zhǔn)骄幊?它能使代碼簡單易讀,書寫方便 */
person.eat.sleep.eat.sleep.sleep;
鏈?zhǔn)骄幊處?shù)的寫法:將block作為返回值
Person.h
- (Person *(^)(NSString *food))eat3;
- (Person *(^)(NSString *where))sleep3;
Person.m
- (Person *(^)(NSString *food))eat3
{
return ^(NSString *food) {
NSLog(@"吃:%@ ",food);
return self;
};
}
- (Person *(^)(NSString *where))sleep3
{
return ^(NSString *where) {
NSLog(@"睡在:%@上",where);
return self;
};
}
ViewController.m
Person *person = [[Person alloc] init];
/** 鏈?zhǔn)?+ 函數(shù)式寫法 */
person.sleep3(@"床").eat3(@"蘋果").eat3(@"香蕉").sleep3(@"沙發(fā)");
返回值block不帶參數(shù)瓤逼,()不傳參即可
person.sleep3().eat3().eat3().sleep3();
函數(shù)式編程
函數(shù)式編程思想:是將操作盡可能寫在一起!嵌套的函數(shù)!!
本質(zhì):就是往方法里面?zhèn)魅隑lock,方法中嵌套Block調(diào)用.
Person.h
@property (nonatomic, assign) NSInteger result;
- (Person *)calculator:(NSInteger(^)(NSInteger result))block;
Person.m
/** 返回調(diào)用者本身笼吟,獲取其它屬性和方法 */
- (Person *)calculator:(NSInteger(^)(NSInteger result))block
{
_result = block(_result);
return self;
}
ViewController.m
Person *person = [[Person alloc] init];
/** 計算器 */
Person *calculatPerson = [person calculator:^NSInteger(NSInteger result) {
result = result + 10;
result = result*10;
return result;
}];
NSLog(@"%ld", calculatPerson.result);
函數(shù)+鏈?zhǔn)骄幊?/h4>
若將函數(shù)和鏈?zhǔn)骄幊探Y(jié)合,我們的程序?qū)l(fā)出藝術(shù)的火花
典型案例:Masonry界面布局框架
//創(chuàng)建一個View
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
//鏈?zhǔn)骄幊趟枷胩攸c:方法返回值必須要有方法調(diào)用者!!
//添加約束 -- make約束制造者!!
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
//設(shè)置約束 每次調(diào)用left\top就是將約束添加到數(shù)組中!
/*
MASConstraint * (^block)(id) = make.left.top.equalTo;
MASConstraint * mk = block(@10);
mk.top;
*/
make.left.top.equalTo(@10);
make.right.bottom.equalTo(@-10);
/**
mas_makeConstraints執(zhí)行流程:
1.創(chuàng)建約束制造者M(jìn)ASConstraintMaker,并且綁定控件,生成一個保存所有約束的數(shù)組
2.執(zhí)行mas_makeConstraints傳入的Block
3.讓約束制造者安裝約束!
* 1.清空之前的所有約束
* 2.遍歷約束數(shù)組,一個一個安裝
*/
}];
我們可以模仿Masonry 寫一個簡單的加法計算器
addCalculator.h
@property (nonatomic, assign) NSInteger sumresult;
- (addCalculator * (^)(NSInteger sumresult))add;
addCalculator.m
- (addCalculator * (^)(NSInteger sumresult))add
{
return ^(NSInteger sumresult) {
_sumresult += sumresult;
return self;
};
}
Person.h
// 函數(shù)鏈?zhǔn)骄幊?@property (nonatomic, assign) NSInteger result;
- (Person *)makecalculator:(void (^)(addCalculator *addcalculator))block;
Person.m
- (Person *)makecalculator:(void (^)(addCalculator *addcalculator))block
{
addCalculator *add = [[addCalculator alloc] init];
if (block) {
block(add);
}
self.result = add.sumresult;
return self;
}
/** 函數(shù)鏈?zhǔn)骄幊?*/
ViewController.m
Person *person = [[Person alloc] init];
[person makecalculator:^(addCalculator *addcalculator) {
addcalculator.add(10).add(30);
}];
NSLog(@"person : %ld", person.result);
響應(yīng)式編程
解釋:在程序開發(fā)中:a = b + c賦值之后 b 或者 c 的值變化后抛姑,a 的值不會跟著變化赞厕;
響應(yīng)式編程目標(biāo)就是,如果 b 或者 c 的數(shù)值發(fā)生變化定硝,a 的數(shù)值會同時發(fā)生變化皿桑;
響應(yīng)編程的經(jīng)典案例:KVO
響應(yīng)式編程框架:ReactiveCocoa(RAC)
RAC學(xué)習(xí)可參考SkyHarute 簡書博客