内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

iOS-block的妙用:链式编程(经典应用:Masonry)

2018-12-03 21:02 出处:清屏网 人气: 评论(0

iOS开发当中有一个很特殊的存在,这个特殊就是block。在OC当中实现某一个功能都是一个 响应对象 调用一个 响应方法 ,简而言之就是Target-Action。

以UIButton为例:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

UIButton的事件就是一个响应对象和一个响应方法之间的一一映射。

与UIButton这种不同,block则不一样,其根本不需要响应对象,如下:

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的实现 。上述代码中'='后面的便是block的实现,包含了参数与返回值

3. block的调用 。上述代码中的 LogString(@"12345") 就是对block的调用

今天小编就来说说block的另外一项应用: 链式编程

说到链式编程最经典的应用便是Masonry了,以下便是Masonry的简单代码:

[self.nicknameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.top.equalTo(view).priorityHigh();
    }];

其中可以看到对于make这个MASConstraintMaker对象的设置是以 一系列的点语法来实现的

当然,这个 leadingtop 也是很容易实现的,无非就是以系列的 get 方法而已。但是后面的 equalTo(view)priorityHigh() 是什么鬼?我们点进去:

Masonry源码

这个时候可以看到 equalTo方法的返回值是一个block,而equalTo里面则是一个block的声明,并且将这个block给return了

如此我们在调用 equalTo(view) 的时候经历了以下步骤:

1. 调用equalTo方法的对象是MASConstraint,equalTo方法里面声明了一个block和block的实现

2. MASConstraint对象调用equalTo方法实际上是返回了一个block,这个block的返回值还是MASConstraint对象

3. 步骤2获取到一个block,这个block参数是一个id类型的数据,那么equalTo后面的view参数实际上就作为block的参数了,这也就实现了一个block的调用

4. 因为block的返回值是MASConstraint对象,所以经历步骤3之后的值实际上还是MASConstraint,调用priorityHigh()就又回到了步骤1

说来说去是不是绕糊涂了?实际上这无非就是 block的声明,block的实现与block的实现 这三个步骤的另外一种变体。

接下来我们依据上面总结的Masonry的步骤来对UILabel实现链式编程:

1. 声明一个UILabel的分类 ,如下:

UILabel的分类

2. 初始化UILabel的方法声明 。在 UILabel+Additions.h 里声明一个叫label的方法,这个方法没有参数,返回值是一个block,这个block的返回值是一个UILabel对象,block的参数是CGRect的结构体。

/**
  * 初始化label,此方法是类方法且没有参数
  * 此方法的返回值是一个block
  * 这个block参数为一个CGRect的参数
  * 返回值还是UILabel对象,用来实现链式编程
 */
+ (UILabel *(^)(CGRect frame))label;

3. 初始化UILabel的方法实现 。在 UILabel+Additions.m 实现 label 方法,最主要是实现block,这个在block里实现UILabel的创建,并将这个block返回,如下:

+ (UILabel * _Nonnull (^)(CGRect))label {
    // 声明并实现一个block,并返回
    return ^(CGRect frame) {
        // 根据传过来的frame参数初始化UILabel,并返回
        return [[UILabel alloc] initWithFrame:frame];
    };
}

同理,设置UILabel的text和textColor也是如此,以下便是代码:

UILabel+Additions.h 进行方法的声明:

// 对象方法
- (UILabel *(^)(NSString *title))title;
- (UILabel *(^)(UIColor *titleColor))titleColor;

UILabel+Additions.m 对方法进行实现:

- (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;
    };
}

应用代码:

UILabel *label = UILabel.label(CGRectMake(100, 100, 200, 50)).
                     title(@"链式编程的应用").
                     titleColor([UIColor greenColor]);
    label.backgroundColor = [UIColor redColor];
    [self.view addSubview:label];

效果:

效果图

分享给小伙伴们:
本文标签: 链式编程MasonryiOS

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号