iOS開發(fā)當中有一個很特殊的存在,這個特殊就是block。在OC當中實現(xiàn)某一個功能都是一個響應(yīng)對象調(diào)用一個響應(yīng)方法捂寿,簡而言之就是Target-Action驳概。
以UIButton為例:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
UIButton的事件就是一個響應(yīng)對象和一個響應(yīng)方法之間的一一映射稚照。
與UIButton這種不同咐熙,block則不一樣棋恼,其根本不需要響應(yīng)對象,如下:
void (^LogString)(NSString *string) = ^(NSString *string) {
NSLog(@"這是一個用來打印log的block,需要打印的字符串為:%@", string);
};
LogString(@"12345");
block的使用無非是以下三個步驟:
1.block的聲明。上述代碼中的void (^LogString)(NSString *string
就是將void (^)(NSString *string)
聲明成一個叫LogString
的block
2.block的實現(xiàn)土陪。上述代碼中'='后面的便是block的實現(xiàn)鬼雀,包含了參數(shù)與返回值
3.block的調(diào)用励烦。上述代碼中的LogString(@"12345")
就是對block的調(diào)用
今天小編就來說說block的另外一項應(yīng)用:鏈式編程。
說到鏈式編程最經(jīng)典的應(yīng)用便是Masonry了,以下便是Masonry的簡單代碼:
[self.nicknameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.top.equalTo(view).priorityHigh();
}];
其中可以看到對于make這個MASConstraintMaker對象的設(shè)置是以一系列的點語法來實現(xiàn)的域滥。
當然荆忍,這個leading和top也是很容易實現(xiàn)的微宝,無非就是以系列的get方法而已。但是后面的equalTo(view)和priorityHigh()是什么鬼?我們點進去:
這個時候可以看到equalTo方法的返回值是一個block玩徊,而equalTo里面則是一個block的聲明约啊,并且將這個block給return了。
如此我們在調(diào)用equalTo(view)的時候經(jīng)歷了以下步驟:
1.調(diào)用equalTo方法的對象是MASConstraint佣赖,equalTo方法里面聲明了一個block和block的實現(xiàn)
2.MASConstraint對象調(diào)用equalTo方法實際上是返回了一個block恰矩,這個block的返回值還是MASConstraint對象
3.步驟2獲取到一個block,這個block參數(shù)是一個id類型的數(shù)據(jù)憎蛤,那么equalTo后面的view參數(shù)實際上就作為block的參數(shù)了外傅,這也就實現(xiàn)了一個block的調(diào)用
4.因為block的返回值是MASConstraint對象,所以經(jīng)歷步驟3之后的值實際上還是MASConstraint俩檬,調(diào)用priorityHigh()就又回到了步驟1
說來說去是不是繞糊涂了萎胰?實際上這無非就是block的聲明,block的實現(xiàn)與block的實現(xiàn)這三個步驟的另外一種變體棚辽。
接下來我們依據(jù)上面總結(jié)的Masonry的步驟來對UILabel實現(xiàn)鏈式編程:
1.聲明一個UILabel的分類技竟,如下:
2.初始化UILabel的方法聲明。在UILabel+Additions.h
里聲明一個叫l(wèi)abel的方法屈藐,這個方法沒有參數(shù)榔组,返回值是一個block,這個block的返回值是一個UILabel對象联逻,block的參數(shù)是CGRect的結(jié)構(gòu)體搓扯。
/**
* 初始化label,此方法是類方法且沒有參數(shù)
* 此方法的返回值是一個block
* 這個block參數(shù)為一個CGRect的參數(shù)
* 返回值還是UILabel對象,用來實現(xiàn)鏈式編程
*/
+ (UILabel *(^)(CGRect frame))label;
3.初始化UILabel的方法實現(xiàn)包归。在UILabel+Additions.m
實現(xiàn)label方法锨推,最主要是實現(xiàn)block,這個在block里實現(xiàn)UILabel的創(chuàng)建,并將這個block返回换可,如下:
+ (UILabel * _Nonnull (^)(CGRect))label {
// 聲明并實現(xiàn)一個block椎椰,并返回
return ^(CGRect frame) {
// 根據(jù)傳過來的frame參數(shù)初始化UILabel,并返回
return [[UILabel alloc] initWithFrame:frame];
};
}
同理沾鳄,設(shè)置UILabel的text和textColor也是如此俭识,以下便是代碼:
在UILabel+Additions.h
進行方法的聲明:
// 對象方法
- (UILabel *(^)(NSString *title))title;
- (UILabel *(^)(UIColor *titleColor))titleColor;
在UILabel+Additions.m
對方法進行實現(xiàn):
- (UILabel * _Nonnull (^)(NSString * _Nonnull))title {
return ^(NSString *title) {
self.text = title;
// 返回self就可以了
return self;
};
}
- (UILabel * _Nonnull (^)(UIColor * _Nonnull))titleColor {
return ^(UIColor *titleColor) {
self.textColor = titleColor;
// 返回self就可以了
return self;
};
}
應(yīng)用代碼:
UILabel *label = UILabel.label(CGRectMake(100, 100, 200, 50)).
title(@"鏈式編程的應(yīng)用").
titleColor([UIColor greenColor]);
label.backgroundColor = [UIColor redColor];
[self.view addSubview:label];
效果:
最后打個廣告,個人第三方庫:
UDUserDefaultsModel:NSUserDefaults的改進方案
YIIFMDB:直接操作Model進行增刪改查洞渔,數(shù)學(xué)運算等套媚,且sql語句易于管理