[iOS開發]方法的封裝之鏈式編程

面向對象的語言有三個特點,封裝 繼承 多態,這會說的鏈式編程是基于封裝這一特點的延伸

Masonry是iOS開發中經常使用的框架,它就是一個鏈式編程的經典例子,把控件的約束條件寫在一個block里面,一次性完成對某個控件的約束,而且使用點語法寫起來干凈瀟灑,省去了OC中最反人類的[],當然,最終使用與否還是看個人習慣以及團隊協作的便利性;

鏈式編程的思路之神奇的點語法

用過Masonry的朋友們會發現雖然里面在一次又一次的調用方法,可是卻沒有用到[],而是頻繁的用點來操作.這其實是一個開發者容易遺漏的神奇地方.
eg.

    NSMutableString *mutableString = [NSMutableString string];
    mutableString.copy;//1
    [mutableString copy];//2

寫法1會報"property access result unused - getters should not be used for side effects"這個么一個警告,這個不受影響,因為我們現在沒有將執行結果賦給其他變量所有會有這個警告使用[]調用方法即使方法有返回值在我們不接收返回值的時候也不會出現警告.我們將寫法1寫成這樣就可以將警告消除.

(void)mutableString.copy;

就實際的使用來看,二者并沒有什么區別,那我們當然會想,這是不是Foundation框架在內部進行了什么處理才可以這樣調用了,于是我們照葫蘆畫瓢.

- (void)hehe{
    NSLog(@"123,hehe");
}
- (void)viewDidLoad {
    [super viewDidLoad];
    (void)self.hehe;
}

控制臺結果是

[25253:1097886] 123,hehe

這么一來我們的鏈式編程點語法就的秘密就解開了.由于鏈式點語法的返回值我們每次都會循環使用(實際上返回值是一個返回值為self的block),所以我們也不會看到鏈式點語法中(void)的出現.

奇葩的返回值

大家一定都多多少看過Masonry框架的底層代碼,可以看到每次點語法的調用返回的總是一個約束.
eg.

- (MASConstraint *)edges
- (MASConstraint * (^)(id))equalTo

調用的的時候是

make.edges.mas_equalTo(0);

所以單純返回一個可以循環調用的類型就可以進行基本的鏈式編程了,可是如果要接參,沒辦法,我們只能把返回值類型寫成==>帶參數的返回值為可循環類型的block.

開工-來一個小demo

#import <UIKit/UIKit.h>
@class JJButton;

typedef JJButton *(^JJButtonStringBlock)(NSString *aName);//typedef一個返回值為JJButton* 參數為NSString* 的名字為JJButtonStringBlock的block,方便以后快速定義該類型block

typedef JJButton *(^JJButtonIntegerBlcok)(NSUInteger aNumber);

typedef JJButton *(^JJButtonColorBlock)(UIColor *aColor);

@interface JJButton : UIButton

- (JJButtonStringBlock)imageName;

- (JJButtonStringBlock)title;

- (JJButtonIntegerBlcok)titleFont;

- (JJButtonColorBlock)textColor;

+ (JJButton *)makeJJButton:(void (^)(JJButton *))block;//該方法為工廠方法,能夠快速創建一個JJButton,在一個參數為block的方法中一次性設置好你需要的JJButton

@end

不多說了,下面是方法的實現

#import "JJButton.h"

@implementation JJButton

- (JJButtonStringBlock)imageName{
    return ^JJButton *(NSString *aName){
        [self setImage:[UIImage imageNamed:aName] forState:UIControlStateNormal];
        NSLog(@"imageName");
        return self;
    };
}

- (JJButtonStringBlock)title{
    return ^JJButton *(NSString *aName){
        [self setTitle:aName forState:UIControlStateNormal];
        NSLog(@"title");
        return self;
    };
}

- (JJButtonIntegerBlcok)titleFont{
    return ^JJButton *(NSUInteger aNumber){
        self.titleLabel.font = [UIFont systemFontOfSize:aNumber];
        NSLog(@"titleFont");
        return self;
    };
}

- (JJButtonColorBlock)textColor{
    return ^JJButton *(UIColor *aColor){
        [self setTitleColor:aColor forState:UIControlStateNormal];
        NSLog(@"textColor = %@",aColor);
        return self;
    };
}

+ (JJButton *)makeJJButton:(void (^)(JJButton *))block{
    JJButton * button = [[JJButton alloc] init];
    block(button);
    return button;
}

@end

調用

    JJButton *myButton = ({
        JJButton *button = [[JJButton alloc] init];
        button.title(@"heiheihei").imageName(@"3").titleFont(15).textColor([UIColor blackColor]);
        button.frame = CGRectMake(100, 100, 100, 100);
        [button addTarget:self action:@selector(didClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
        button;
    });

上訴方法是不適用工廠方法的調用,我使用了GCC語法,這種語法看上去比較規整.

下面是工廠方法

    [JJButton makeJJButton:^(JJButton *button) {
        button.title(@"xixixi").imageName(@"abc").titleFont(20).textColor([UIColor orangeColor]);
        button.frame = CGRectMake(100, 250, 100, 100);
        [self.view addSubview:button];
        [button addTarget:self action:@selector(didClick:) forControlEvents:UIControlEventTouchUpInside];
    }];

這種方法大家應該就分廠熟悉了,它與Masonry那種鏈式編程寫法非常相似了,在工廠方法中我們在類方法內部進行了初始化,相當于進行了更加徹底的封裝.
蘿卜青菜各有所愛哈~

版權聲明:本文版權歸本文作者所有,始發于簡書,如需轉載請聯系作者,違者必究.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,198評論 4 61
  • 早起第一件事!紅袋鼠系列是我姑娘的很喜歡的一套書!這套書有拼音閱讀,有專注力游戲,有走迷宮,還有排列數字!而且是超...
    愛上閱讀做好媽媽閱讀 109評論 0 0
  • 多目標優化 目標優化問題一般地就是指通過一定的優化算法獲得目標函數的最優化解。當優化的目標函數為一個時稱之為單目標...
    NeXtoW閱讀 11,297評論 0 7
  • 這兩雙有右邊那個就要右邊的,沒有的話左邊的也行。 這三雙有紅色的要一雙紅色,沒有的話黃的也可以,再沒有的話就要白的。
    十甫寸鳶閱讀 146評論 0 0