文章目录
  1. 1. 链式编程
    1. 1.1. 介绍
    2. 1.2. 实现
    3. 1.3. 总结

链式编程

@(iOS)

最近研究了一下链式编程,但是感觉项目中用处不是很多。

介绍

  • 1.什么时候使用链式编程?
  • 在面向一些过程化处理的时候(给View加约束,都可以看成需要一步步完成的过程),需要将这些“过程”拆分,然后在“组合”这些“过程”的时候,就可以使用链式编程,使得代码更加清晰,增加阅读性。
  • 2、链式编程核心实现
  • 实现链式编程的关键就是声明一个block的属性,而这个block返回值必须还是一个对象(根据业务需求不同,可以返回的是这个对象实例本身,也可以是这个类的另一个实例,更可以是另一个类的实例对象)。
  • 函数式编程在iOS中是借由block实现的,通过声明一个block,类似于定义了一个“函数”,再将这个“函数”传递给调用的方法,以此来实现对调用该方法时中间一些过程或者对结果处理的“自定义”,而其内部的其他环节完全不需要暴露给调用者。实际上,调用者也根本不需要知道。

  • 3、控制调用顺序的话,可以使用协议,返回准守某些协议的对象,这样接下来就会弹出满足指定协议的方法。

实现

  • 这里封装一个UIButton来设置相关属性
  • 这里控制使用顺序,必须先init才能调用其他方法。
  • 使用方式
- (void)viewDidLoad {
[super viewDidLoad];
SLQButton<UIButtonSettingProtocal> *but = [[SLQButton<UIButtonSettingProtocal> alloc] initWithFrame:CGRectMake(50, 100, 100, 50)];
but.Title(@"点我啊",UIControlStateNormal).TitleColor([UIColor greenColor],UIControlStateNormal).EventBlock(self,@selector(butClick),UIControlEventTouchUpInside);
[self.view addSubview:but];

SLQButton *but2 = [SLQButton makeButton:^(SLQButton<UIButtonInitProtocal> *button) {
button.Init(CGRectMake(50,200, 100, 50)).NormalTitle(@"哈哈哈").NormalTitleColor([UIColor redColor]);
}];
[self.view addSubview:but2];
}


- (void)butClick {
NSLog(@"hahaha");
}
  • 源代码
//
// SLQButton.h
// SLQPersonLinkTest
//
// Created by MrSong on 16/12/26.
// Copyright © 2016年 song. All rights reserved.
// 链式编程Demo

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

@protocol UIButtonInitProtocal;
@protocol UIButtonSettingProtocal;

#pragma mark - Normal
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalTitle)(NSString *title);
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalTitleColor)(UIColor *titleColor);
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalTitleShadowColor)(UIColor *titleShadowColor);
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalImage)(UIImage *image);
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalBackgroundImage)(UIImage *backgroundImage);
typedef SLQButton<UIButtonSettingProtocal> *(^SetNormalAttributedTitle)(NSAttributedString *attributedTitle);
typedef SLQButton<UIButtonSettingProtocal> *(^AddTouchUpInsidEventBlock)(id target,SEL action);

typedef SLQButton<UIButtonSettingProtocal> *(^SetBackgroundColor)(UIColor *backgroundColor);

#pragma mark - detail
typedef SLQButton<UIButtonSettingProtocal> *(^InitButton)(CGRect frame);
typedef SLQButton<UIButtonSettingProtocal> *(^SetTitle)(NSString *title,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^SetTitleColor)(UIColor *titleColor,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^SetTitleShadowColor)(UIColor *titleShadowColor,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^SetImage)(UIImage *image,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^SetBackgroundImage)(UIImage *backgroundImage,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^SetAttributedTitle)(NSAttributedString *attributedTitle,UIControlState state);
typedef SLQButton<UIButtonSettingProtocal> *(^AddEventBlock)(id target,SEL action,UIControlEvents event);


#pragma mark - 协议
@protocol UIButtonInitProtocal <NSObject>
@property (nonatomic, strong, readonly) InitButton Init;
@end

@protocol UIButtonSettingProtocal <NSObject>

/**
设置属性协议
*/
#pragma mark Normal
@property (nonatomic, strong, readonly) SetNormalTitle NormalTitle;
@property (nonatomic, strong, readonly) SetNormalTitleColor NormalTitleColor;
@property (nonatomic, strong, readonly) SetNormalTitleShadowColor NormalTitleShadowColor;
@property (nonatomic, strong, readonly) SetNormalImage NormalImage;
@property (nonatomic, strong, readonly) SetNormalBackgroundImage NormalBackgroundImage;
@property (nonatomic, strong, readonly) SetNormalAttributedTitle NormalAttributedTitle;
@property (nonatomic, strong, readonly) AddTouchUpInsidEventBlock TouchUpInsidEventBlock;

@property (nonatomic, strong, readonly) SetBackgroundColor BackgroundColor;

@property (nonatomic, strong, readonly) SetTitle Title;
@property (nonatomic, strong, readonly) SetTitleColor TitleColor;
@property (nonatomic, strong, readonly) SetTitleShadowColor TitleShadowColor;
@property (nonatomic, strong, readonly) SetImage Image;
@property (nonatomic, strong, readonly) SetBackgroundImage BackgroundImage;
@property (nonatomic, strong, readonly) SetAttributedTitle AttributedTitle;
@property (nonatomic, strong, readonly) AddEventBlock EventBlock;
@end
@interface SLQButton : UIButton
+ (SLQButton *)makeButton:(void(^)(SLQButton<UIButtonInitProtocal> *button))block;

@end
  • 源代码
//
// SLQButton.m
// SLQPersonLinkTest
//
// Created by MrSong on 16/12/26.
// Copyright © 2016年 song. All rights reserved.
//

#import "SLQButton.h"

@interface SLQButton ()
<UIButtonSettingProtocal,UIButtonInitProtocal
>
@end

@implementation SLQButton

- (id<UIButtonSettingProtocal> )initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}

+ (SLQButton *)makeButton:(void(^)(SLQButton<UIButtonInitProtocal> *button))block{
if (block) {
SLQButton<UIButtonInitProtocal> *per = [[SLQButton alloc] init];
block(per);
return per;
}
return nil;
}

- (InitButton)Init {
return ^(CGRect frame) {
self.frame = frame;
return self;
};
}
#pragma mark - Normal

- (SetNormalTitle)NormalTitle {
return ^(NSString *title) {
[self setTitle:title forState:UIControlStateNormal];
return self;
};
}

- (SetNormalTitleColor)NormalTitleColor {
return ^(UIColor *titleColor) {
[self setTitleColor:titleColor forState:UIControlStateNormal];
return self;
};
}

- (SetNormalTitleShadowColor)NormalTitleShadowColor {
return ^(UIColor *titleShadowColor) {
[self setTitleShadowColor:titleShadowColor forState:UIControlStateNormal];
return self;
};
}

- (SetNormalImage)NormalImage {
return ^(UIImage *image) {
[self setImage:image forState:UIControlStateNormal];
return self;
};
}

- (SetNormalBackgroundImage)NormalBackgroundImage {
return ^(UIImage *backgroundImage) {
[self setImage:backgroundImage forState:UIControlStateNormal];
return self;
};
}

- (SetNormalAttributedTitle)NormalAttributedTitle {
return ^(NSAttributedString *attributedTitle){
[self setAttributedTitle:attributedTitle forState:UIControlStateNormal];
return self;
};
}

- (AddTouchUpInsidEventBlock)TouchUpInsidEventBlock {
return ^(id target, SEL action) {
[self addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
return self;
};
}


#pragma mark - Detail

- (SetTitle)Title {
return ^(NSString *title,UIControlState state) {
[self setTitle:title forState:state];
return self;
};
}

- (SetTitleColor)TitleColor {
return ^(UIColor *titleColor,UIControlState state) {
[self setTitleColor:titleColor forState:state];
return self;
};
}

- (SetTitleShadowColor)TitleShadowColor {
return ^(UIColor *titleShadowColor,UIControlState state) {
[self setTitleShadowColor:titleShadowColor forState:state];
return self;
};
}

- (SetImage)Image {
return ^(UIImage *image,UIControlState state) {
[self setImage:image forState:state];
return self;
};
}

- (SetBackgroundImage)BackgroundImage {
return ^(UIImage *backgroundImage,UIControlState state) {
[self setImage:backgroundImage forState:state];
return self;
};
}

- (SetAttributedTitle)AttributedTitle {
return ^(NSAttributedString *attributedTitle,UIControlState state){
[self setAttributedTitle:attributedTitle forState:state];
return self;
};
}

- (AddEventBlock)EventBlock {
return ^(id target, SEL action,UIControlEvents event) {
[self addTarget:target action:action forControlEvents:event];
return self;
};
}


#pragma mark - Public
- (SetBackgroundColor)BackgroundColor {
return ^(UIColor *backgroundColor) {
[self setBackgroundColor:backgroundColor];
return self;
};
}


@end

总结

  • 链式编程,猛然一听好牛的感觉,其实不过如此。在业务类中用处不怎么大,但是在工具类中比较适合使用。
  • 当然可以封装一整套UIKit的链式编程的方式,这样创建View是比较简单的。

参考

文章目录
  1. 1. 链式编程
    1. 1.1. 介绍
    2. 1.2. 实现
    3. 1.3. 总结