? ? ? ?我的上一篇文章《iOS程序閃退時(shí)的處理一句代碼搞定異常攔截》中提到了“鏈?zhǔn)骄幊獭保赡苡凶x者關(guān)于“鏈?zhǔn)骄幊獭睍?huì)有些疑問。關(guān)于“鏈?zhǔn)骄幊獭本W(wǎng)上也有這方面的文章,這里就簡單地談一下個(gè)人的一點(diǎn)愚見,拋磚引玉吧,有不對的地方還請各位看官指正。
? ? ? ?先看段代碼
UIBtn(@"btn1").frame_l(CGRectMake(100, 100, 100, 60))
.backgroundColor_l([UIColor redColor])
.action(self, @selector(action1:), UIControlEventTouchUpInside)
.addToView(self.view);
? ? ? ?上面這句代碼,將多行代碼通過.鏈接成一句代碼,這就是鏈?zhǔn)骄幊?,也是鏈?zhǔn)骄幊痰囊粋€(gè)優(yōu)點(diǎn)特點(diǎn)。使用起來很簡潔,可讀性好。
? ? ? ?怎么才能實(shí)現(xiàn)這樣的效果呢?看到.我想很多人會(huì)想到點(diǎn)語法,在oc里我們首先會(huì)想到一個(gè)類的實(shí)例對象的屬性可以被點(diǎn)出來。那么我們怎么才能夠一直點(diǎn)下去呢?那就是不斷地返回這個(gè)實(shí)例對象。繼續(xù)往下想,什么有返回值呢?方法有返回值,但是絕大多數(shù)的方法不能用.調(diào)用啊,WTF!怎么辦。是的,還有Block啊,而且Block還可以聲明成類的屬性。
? ? ? ?分析到這,那么我們就有了一個(gè)基本的思路:在類里的屬性用Block,而且Block的返回值是該類的一個(gè)實(shí)例,然后在這個(gè)Block里我們?nèi)プ鲆恍┫鄳?yīng)的操作。
? ? ? ?下面我以UIButton為例簡單說一下。首先我們創(chuàng)建一個(gè)UIButton的Category,當(dāng)然用繼承也可以。也許有的小伙伴找不到創(chuàng)建的地方,上個(gè)圖。之后的應(yīng)該都會(huì)了。

.h
#import <UIKit/UIKit.h>
@interface UIButton (Link)
@property (nonatomic, copy) UIButton *(^frame_l)(CGRect rect);
@property (nonatomic, copy) UIButton *(^backgroundColor_l)(UIColor *color);
@property (nonatomic, copy) UIButton *(^addToView)(UIView *view);
@property (nonatomic, copy) UIButton *(^action)(id target, SEL selector, UIControlEvents events);
UIButton * UIBtn(id name);
@end
- 這里聲明了四個(gè)Block,分別用來設(shè)置frame,backgroundColor,要添加到的父視圖,以及Action點(diǎn)擊事件
- 下面的c方法,是用來創(chuàng)建實(shí)例對象的,里面的參數(shù)相當(dāng)于對象名,就不用這樣
[UIButton buttonWithType:UIButtonTypeCustom];創(chuàng)建了,寫起來更整潔
再來.m
#import "UIButton+Link.h"
UIButton *button;
@implementation UIButton (Link)
-(UIButton *(^)(CGRect))frame_l {
return ^(CGRect fra) {
button.frame = fra;
return button;
};
}
-(void)setFrame_l:(UIButton *(^)(CGRect))frame_l {};
-(UIButton *(^)(UIColor *))backgroundColor_l {
return ^(UIColor *color) {
button.backgroundColor = color;
return button;
};
}
-(void)setBackgroundColor_l:(UIButton *(^)(UIColor *))backgroundColor_l {};
-(UIButton *(^)(UIView *))addToView {
return ^(UIView *view) {
[view addSubview:button];
return button;
};
}
-(void)setAddToView:(UIButton *(^)(UIView *))addToView {};
-(UIButton *(^)(id, SEL, UIControlEvents))action {
return ^(id target, SEL selector, UIControlEvents events) {
[button addTarget:target action:selector forControlEvents:events];
return button;
};
}
-(void)setAction:(UIButton *(^)(id, SEL, UIControlEvents))action {};
@end
UIButton * UIBtn(id name) {
button = [UIButton buttonWithType:UIButtonTypeCustom];
return button;
}
-
.m主要就是實(shí)現(xiàn)屬性的getter和setter方法,這里實(shí)現(xiàn)setter是為了消除警告 - c方法中我們對全局的button對象初始化,然后每個(gè)屬性的getter方法都返回這個(gè)對象
? ? ? ?這樣我們在使用時(shí),就達(dá)到了文章開頭那段代碼的效果,實(shí)現(xiàn)了“鏈?zhǔn)骄幊獭???梢砸恢秉c(diǎn)點(diǎn)點(diǎn)了
? ? ? ?但是現(xiàn)在Xcode對Block的提示不是太友好

addToView不會(huì)自動(dòng)補(bǔ)齊后面的參數(shù)
? ? ? ?就說這么多吧,有興趣的童鞋可以繼續(xù)添加屬性設(shè)置。
最后來個(gè)彩蛋,關(guān)于Block
- 在調(diào)用Block時(shí)我們都會(huì)先判斷其是否為nil,防止崩潰,通常是這樣的
if (block) {
block();
}
其實(shí)還可以這樣
!block ? : block();
? ? ? ?時(shí)間倉促,文章有誤之處還請各位留言指正。技術(shù)無止境,共同進(jìn)步,寫出優(yōu)雅的代碼,是我不變的追求。