[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那种链式编程写法非常相似了,在工厂方法中我们在类方法内部进行了初始化,相当于进行了更加彻底的封装.
萝卜青菜各有所爱哈~

版权声明:本文版权归本文作者所有,始发于简书,如需转载请联系作者,违者必究.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 早起第一件事!红袋鼠系列是我姑娘的很喜欢的一套书!这套书有拼音阅读,有专注力游戏,有走迷宫,还有排列数字!而且是超...
    爱上阅读做好妈妈阅读 104评论 0 0
  • 多目标优化 目标优化问题一般地就是指通过一定的优化算法获得目标函数的最优化解。当优化的目标函数为一个时称之为单目标...
    NeXtoW阅读 11,112评论 0 7
  • 这两双有右边那个就要右边的,没有的话左边的也行。 这三双有红色的要一双红色,没有的话黄的也可以,再没有的话就要白的。
    十甫寸鸢阅读 142评论 0 0