关于“链式编程”网上也有这方面的文章,这里就简单地谈一下个人的一点愚见,抛砖引玉吧,有不对的地方还请各位看官指正。
       先看段代码

UIBtn(@"btn1").frame_l(CGRectMake(100, 100, 100, 60))
              .backgroundColor_l([UIColor redColor])
              .action(self, @selector(action1:), UIControlEventTouchUpInside)
              .addToView(self.view);

       上面这句代码,将多行代码通过.链接成一句代码,这就是链式编程,也是链式编程的一个优点特点。使用起来很简洁,可读性好。
       怎么才能实现这样的效果呢?看到.我想很多人会想到点语法,在oc里我们首先会想到一个类的实例对象的属性可以被点出来。那么我们怎么才能够一直点下去呢?那就是不断地返回这个实例对象。继续往下想,什么有返回值呢?方法有返回值,但是绝大多数的方法不能用.调用啊,WTF!怎么办。是的,还有Block啊,而且Block还可以声明成类的属性。
       分析到这,那么我们就有了一个基本的思路:在类里的属性用Block,而且Block的返回值是该类的一个实例,然后在这个Block里我们去做一些相应的操作。
       下面我以UIButton为例简单说一下。首先我们创建一个UIButton的Category,当然用继承也可以。也许有的小伙伴找不到创建的地方,上个图。之后的应该都会了。
996fdbf64d7fc2b064305576dae3ebc6.webp
接下来上代码(一块来吧,我觉得这样直观一些,后面再分开说),先来.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
  • 这里声明了四个Block,分别用来设置frame,backgroundColor,要添加到的父视图,以及Action点击事件
  • 下面的c方法,是用来创建实例对象的,里面的参数相当于对象名,就不用这样[UIButton buttonWithType:UIButtonTypeCustom];创建了,写起来更整洁

    再来.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主要就是实现属性的getter和setter方法,这里实现setter是为了消除警告
  • c方法中我们对全局的button对象初始化,然后每个属性的getter方法都返回这个对象

       这样我们在使用时,就达到了文章开头那段代码的效果,实现了“链式编程”。可以一直点点点了
       但是现在Xcode对Block的提示不是太友好
cee19e8829b958401223bd0c695153e4.webp
当我们按下回车之后,只会出现addToView不会自动补齐后面的参数

       就说这么多吧,有兴趣的童鞋可以继续添加属性设置。

最后来个彩蛋,关于Block

  • 在调用Block时我们都会先判断其是否为nil,防止崩溃,通常是这样的

    if (block) {
          block();
      }

    其实还可以这样

    !block ? : block();

           时间仓促,文章有误之处还请各位留言指正。技术无止境,共同进步,写出优雅的代码,是我不变的追求。

分类: iOS 标签: iOS

评论

暂无评论数据

暂无评论数据

目录