1.什么是鏈式語法
簡單的是說就是可以通過OC的點語法去調(diào)用方法甚至是連續(xù)調(diào)用多個方法,雖然OC本來可以通過點語法去調(diào)用方法,但是只支持調(diào)用無參數(shù)的方法,如果調(diào)用有參的方法則會編譯報錯。
2.鏈式語法的結(jié)構(gòu)
鏈式語法主要包含 點語法、小括號調(diào)用、連續(xù)訪問 三部分。
1.點語法在OC中常見的2個使用場景
- 調(diào)用類屬性
當我們給一個類添加屬性后,系統(tǒng)會自動生成get、set方法我們就可以使用點語法來訪問屬性
- 調(diào)用無參數(shù)的方法
例如tableView的reloadData方法,我們也可以通過tableView.reloadData去調(diào)用
2.為什么鏈式語法可以使用()小括號?
因為鏈式語法中的返回值是一個block,所以調(diào)用方法后可以接
()小括號
3.為什么鏈式語法可以連續(xù)訪問?
因為鏈式語法中返回的block的返回值是實例本身,所以又可以繼續(xù)調(diào)用實例擁有的方法。
如:
//testChainVC類.m文件
@implementation testChainVC
- (testChainVC *(^)(NSString *))firstChain{
return ^testChainVC *(NSString *param){
NSLog(@"這是鏈語法中設(shè)置的參數(shù):%@",param);
return self;
};
}
- (testChainVC *(^)(NSString *))secondChain{
return ^testChainVC *(NSString *param){
NSLog(@"這是鏈語法中第二個方法的參數(shù):%@",param);
return self;
};
}
@end
//ViewController類.m文件
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
testChainVC *testVc=[testChainVC new];
testVc.firstChain(@"第一").secondChain(@"第二");
}
@end
2.使用鏈式語法的優(yōu)缺點
優(yōu)點:
1.可讀性高
2.代碼簡潔
缺點:
1.調(diào)用時消耗的時間比普通調(diào)用方法消耗的時間更長。
因為使用block的方式,要通過get方法獲取block屬性,然后再執(zhí)行block方法,比普通調(diào)用方法多了一個步驟。
2.使用不當容易導(dǎo)致崩潰。
3.鏈式語法的原理
在鏈式語法中能通過點語法去調(diào)用有參方法主要是靠block的特性。
1.先實現(xiàn)使用括號來傳遞方法參數(shù)
會使用block的都是知道,block可以使用小括號接收參數(shù),那么如果一個方法的返回類型是一個帶參的block,是不是就可以實現(xiàn)通過點語法加小括號去調(diào)用有參方法了呢?
1.實現(xiàn)一個返回值為有參block的方法
- (void (^)(int))testMethod{
//聲明一個有參的block
void (^testBlock)(int i) = ^(int i){
NSLog(@"%d",i);
};
//返回聲明的block
return testBlock;
}
2.使用點語法去調(diào)用testMethod方法
// self.testMethod 就相當于 [self self.testMethod]
self.testMethod(2);
3.步驟分解
//1.因為testMethod方法的返回類型是一個參數(shù)的block,所以我們可以聲明相同類型的testBlock變量去接收testMethod方法的返回值
void (^testBlock)(int i) =self.testMethod;
//2.再使用block變量調(diào)用去 testBlock 中的代碼
testBlock(2);
//3.因為self.testMethod 本身就返回了block,所以括號中的2可以看做是賦值給了 self.testMethod 方法返回的testBlock
self.testMethod(2);
2.實現(xiàn)方法的連續(xù)調(diào)用
要實現(xiàn)方法的連續(xù)調(diào)用,其實只需要將上一步中的方法的返回值類型修改一下就可以了。
實現(xiàn)步驟:
1.假如使用鏈式語法的是一個testChainVC類的實例變量,那么我們可以在testChainVC類聲明方法的時候,將方法中返回值類型改為帶返回值并且返回值類型為當前類testChainVC的block,block的入?yún)⒖梢愿鶕?jù)自己的需要去定義。
示例代碼如下:
//testChainVC類.h文件
@interface testChainVC : UIViewController
- (testChainVC *(^)(int))testMethod;
- (testChainVC *(^)(NSString *))testSecondMethod;
-
@end
//testChainVC類.m文件
@implementation testChainVC
- (testChainVC *(^)(int))testMethod{
return ^testChainVC *(int param){
NSLog(@"這是鏈語法中第一個方法的參數(shù):%d",param);
return self;
};
}
- (testChainVC *(^)(NSString *))testSecondMethod{
return ^testChainVC *(NSString *param){
NSLog(@"這是鏈語法中第二個方法的參數(shù):%@",param);
return self;
};
}
@end
2.使用testChainVC實例變量連續(xù)調(diào)用方法
//ViewController類.m文件
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
testChainVC *testVc=[testChainVC new];
testVc.testMethod(2).testSecondMethod(@"3");
}
@end
3.執(zhí)行結(jié)果
11:26:56.598851+0800 [21215:1005532] 這是鏈語法中第一個方法的參數(shù):2
11:26:56.598970+0800 [21215:1005532] 這是鏈語法中第二個方法的參數(shù):3
4.關(guān)于block的使用細節(jié)
1.block 是順序執(zhí)行的,并非異步執(zhí)行,你覺得他是異步執(zhí)行的很大一部分原因是因為大部分 block 是用來處理異步回調(diào)的。
2.block 的實現(xiàn)可以不寫返回值類型 除非返回值類型是id:
id(^testBlock)() = ^(){
// 返回值 不為nil 可以不用聲明返回值
return slef;
}
3.如果返回值存在可能為nil的情況.這時必須在實現(xiàn)聲明返回值類型是id,否則報錯
id(^testBlock)() = ^id(){
// 返回 nil 必須在實現(xiàn)聲明返回值類型為id
return nil;
}