標籤:
鏈式編程思想 鏈式編程是什麼
鏈式編程就是將調用多個方法用點文法串連起來,讓代碼更加簡潔和可讀性更高
剛開始接觸鏈式編程是Masonry,用起來真的非常爽
1 |
make.left.right.top.equalTo(self.view); |
這樣一句語句就調用了4個方法
.left調用了left屬性的get方法
.right, .top調用了right和top方法
.equalTo()調用了equalTo方法
這種寫法極大簡化了寫約束的方式
原理
原理就是調用的屬性的類型或者方法的傳回型別為原調用屬性的類型
例如說UILabel
調用了某個方法或者屬性,得到的類型還是UILabel,那麼還可以繼續調用UILabel的屬性或者方法
如何?
看了Masonry,我發現有兩種實現方式
1.用點文法調用方法
這個其實我之前沒發現,寫習慣了用方括弧調用方法
例如建立一個label 可以這樣寫UILabel *label = [[UILabel alloc] init
其實也可以這樣寫UILabel *label = UILabel.alloc.init
不過後種方法幾乎沒人用,蘋果應該也不推薦這種寫法,因為有時候這樣寫是沒有代碼提示的
但是有一個缺點就是不能調用有參數的方法,所以我們只能寫沒有參數的方法
建立一個UIButton的分類
寫兩個方法
1 2 |
- (UIButton *)setTextHello; - (UIButton *)setTextColorRed; |
並且實現
1 2 3 4 5 6 7 8 9 10 11 |
- (UIButton *)setTextColorRed { [self setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; return self; }
- (UIButton *)setImage { [self setImage:[UIImage imageNamed:@"Stan1"] forState:UIControlStateNormal]; return self; } |
然後我們建立一個按鈕的時候就可以這樣寫
1 2 3 4 5 |
//建立一個按鈕 UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight]; button.frame = CGRectMake(100, 100, 100, 100); button.setTextHello.setTextColorRed; [self.view addSubview:button]; |
效果
但是會報一個警告,因為調用的是屬性,但是這個屬性沒有被用到
解決方案是在調用屬性前面加(void)
,這樣就可以了
2.用屬性調用
新建立一個UILabel的分類
如果要傳入參數的話,就返回一個UILabel的block,可以在block裡面實現你想要實現的東西
1 2 3 |
@property(nonatomic,copy) UILabel* (^kText)(NSString *text); @property(nonatomic,copy) UILabel* (^kFont)(NSUInteger fontSize); @property(nonatomic,copy) UILabel* (^kTextColor)(UIColor *color); |
加k是為了易於區分,可以不加的
因為這是在分類裡面的屬性,不會產生setter和getter方法,所以都要自己寫
實現如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
- (UILabel *(^)(NSUInteger))kFont { return ^(NSUInteger font){ [self setFont:[UIFont systemFontOfSize:font]]; return self; }; }
- (UILabel *(^)(NSString *))kText { return ^(NSString *text){ [self setText:text]; return self; }; }
- (UILabel *(^)(UIColor *))kTextColor { return ^(UIColor *color){ [self setTextColor:color]; return self; }; }
- (void)setKFont:(UILabel *(^)(NSUInteger))kFont{} - (void)setKText:(UILabel *(^)(NSString *))kText{} - (void)setKTextColor:(UILabel *(^)(UIColor *))kTextColor{} |
不會用到setter方法,也不能用,所以setter方法設為空白
然後就能愉快的鏈式編程了
然後我再想,假如沒有參數呢,剛開始是想block沒有參數
1 2 3 |
@property(nonatomic,copy) UILabel* (^aText)(); @property(nonatomic,copy) UILabel* (^aFont)(); @property(nonatomic,copy) UILabel* (^aTextColor)(); |
實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
- (UILabel *(^)())aFont { return ^(){ [self setFont:[UIFont systemFontOfSize:16.0f]]; return self; }; }
- (UILabel *(^)())aTextColor { return ^(){ [self setTextColor:[UIColor cyanColor]]; return self; }; }
- (UILabel *(^)())aText { return ^(){ [self setText:@"這還是一個label"]; return self; }; }
- (void)setAFont:(UILabel *(^)())aFont{} - (void)setAText:(UILabel *(^)())aText{} - (void)setATextColor:(UILabel *(^)())aTextColor{} |
後來發現調用的時候還是要這樣
嘗試了一下,最後一個調用能去掉括弧,警示告,能運行,但是沒效果
所以我想為什麼不直接調用屬性
1 2 3 |
@property(nonatomic,strong) UILabel *bText; @property(nonatomic,strong) UILabel *bFont; @property(nonatomic,strong) UILabel *bTextColor; |
getter && setter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
- (UILabel *)bText { [self setText:@"labellabel"]; return self; }
- (UILabel *)bTextColor { [self setTextColor:[UIColor purpleColor]]; return self; }
- (UILabel *)bFont { [self setFont:[UIFont systemFontOfSize:13.0f]]; return self; }
- (void)setBFont:(UILabel *)bFont{} - (void)setBText:(UILabel *)bText{} - (void)setBTextColor:(UILabel *)bTextColor{} |
調用
1 2 3 |
UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(100, 400, 200, 100)]; (void)label3.bTextColor.bText.bFont; [self.view addSubview:label3]; |
如果調用不加(void)還是會警示告
如果想像Masonry那樣的鏈式編程可以這樣寫
1 2 3 |
UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(100, 400, 200, 100)]; label3.bTextColor.bText.kFont(30); [self.view addSubview:label3]; |
這樣就不會警示告,整潔清晰
還發表在 我的個人部落格
Objective-C 鏈式編程思想