OC链式封装进阶/终结篇:属性转为链式编程工具化实现

iOS 中习惯了 Swift 编程之后, 再修改老代码(OC) 感觉调用特别不方便,想链式化一些内层属性,使代码调用更加简单;最终封装为一个链式属性生成器,普通属性一键转链式属性;

需要添加前缀以便和官方默认名称区分开[ 兼容 Swift ];

🌰🌰:将 UICollectionViewFlowLayout 属性链式化

@interface UICollectionViewFlowLayout : UICollectionViewLayout

@property (nonatomic) CGSize itemSize;
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;

@property (nonatomic) UIEdgeInsets sectionInset;

@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds;

@end

工具生成如下:

//
//  UICollectionViewFlowLayout+Chain.h
//  MacTemplet
//
//  Created by Bin Shang on 2021/01/01 19:29
//  Copyright © 2021 Bin Shang. All rights reserved.
//
![WechatIMG423.jpeg](https://upload-images.jianshu.io/upload_images/281882-c01d05f7dfb3895a.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UICollectionViewFlowLayout (Chain)

@property(nonatomic, copy, readonly) UICollectionViewFlowLayout *(^itemSizeChain)(CGSize);

@property(nonatomic, copy, readonly) UICollectionViewFlowLayout *(^scrollDirectionChain)(UICollectionViewScrollDirection);

@property(nonatomic, copy, readonly) UICollectionViewFlowLayout *(^sectionInsetChain)(UIEdgeInsets);

@property(nonatomic, copy, readonly) UICollectionViewFlowLayout *(^sectionHeadersPinToVisibleBoundsChain)(BOOL);

@end

NS_ASSUME_NONNULL_END
#import "UICollectionViewFlowLayout+Chain.h"

@implementation UICollectionViewFlowLayout (Chain)

- (UICollectionViewFlowLayout * (^)(CGSize))itemSizeChain{
    return ^(CGSize value) {
        self.itemSize = value;
        return self;
    };
}

- (UICollectionViewFlowLayout * (^)(UICollectionViewScrollDirection))scrollDirectionChain{
    return ^(UICollectionViewScrollDirection value) {
        self.scrollDirection = value;
        return self;
    };
}

- (UICollectionViewFlowLayout * (^)(UIEdgeInsets))sectionInsetChain{
    return ^(UIEdgeInsets value) {
        self.sectionInset = value;
        return self;
    };
}

- (UICollectionViewFlowLayout * (^)(BOOL))sectionHeadersPinToVisibleBoundsChain{
    return ^(BOOL value) {
        self.sectionHeadersPinToVisibleBounds = value;
        return self;
    };
}

@end

CodeHelper.dmg

附:NSString
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSString (Chain)
///过滤前后空格
@property (nonatomic, strong, readonly) NSString *trimmed;
/// 过滤字符集
@property(nonatomic, copy, readonly) NSString *(^trimmedBy)(NSString *);
@property(nonatomic, copy, readonly) NSString *(^trimmedBySet)(NSCharacterSet *);

@property(nonatomic, copy, readonly) NSString *(^subStringBy)(NSUInteger loc, NSUInteger len);
@property(nonatomic, copy, readonly) NSString *(^subStringFrom)(NSUInteger from);
@property(nonatomic, copy, readonly) NSString *(^subStringTo)(NSUInteger to);

@property(nonatomic, copy, readonly) NSString *(^appending)(NSString *);

@property(nonatomic, copy, readonly) NSString *(^appendingFormat)(NSString *format, ...);

@property(nonatomic, copy, readonly) NSString *(^replacingOccurrences)(NSString *, NSString *, NSStringCompareOptions);
@property(nonatomic, copy, readonly) NSString *(^replacingCharacters)(NSRange, NSString *);

@property(nonatomic, copy, readonly) NSComparisonResult (^compareBy)(NSString *, NSStringCompareOptions);

@property(nonatomic, copy, readonly) BOOL (^equalTo)(NSString *);

@property(nonatomic, copy, readonly) BOOL (^hasPrefix)(NSString *);
@property(nonatomic, copy, readonly) BOOL (^hasSuffix)(NSString *);
@property(nonatomic, copy, readonly) BOOL (^contains)(NSString *);
@property(nonatomic, copy, readonly) NSRange (^rangeBy)(NSString *, NSStringCompareOptions);
@property(nonatomic, copy, readonly, nullable) NSData *(^encoding)(NSStringEncoding);

///componentsSeparatedByString
@property(nonatomic, strong, readonly) NSArray<NSString *> *(^separatedBy)(NSString *);
///componentsSeparatedByString
@property(nonatomic, strong, readonly) NSArray<NSString *> *(^separatedBySet)(NSCharacterSet *);
@end



NS_ASSUME_NONNULL_END
#import "NSString+Chain.h"

@implementation NSString (Chain)

- (NSString *(^)(NSString *))trimmedBy{
    return ^(NSString *value) {
        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:value];
        NSString *result = [self stringByTrimmingCharactersInSet:set];
        return result;
    };
}

- (NSString * (^)(NSCharacterSet * _Nonnull))trimmedBySet{
    return ^(NSCharacterSet *value) {
        return [self stringByTrimmingCharactersInSet:value];
    };
}

- (NSString * (^)(NSUInteger, NSUInteger))subStringBy{
    return ^(NSUInteger loc, NSUInteger len) {
        if (loc + len > self.length) {
            return self;
        }
        NSString *result = [self substringWithRange:NSMakeRange(loc, len)];
        return result;
    };
}

- (NSString * (^)(NSUInteger))subStringFrom{
    return ^(NSUInteger value) {
        return [self substringFromIndex:value];;
    };
}

- (NSString * (^)(NSUInteger))subStringTo{
    return ^(NSUInteger value) {
        return [self substringFromIndex:value];;
    };
}


- (NSString *(^)(NSString * _Nonnull))appending{
    return ^(NSString *value){
        return [self stringByAppendingString:value];
    };
}

- (NSString * _Nonnull (^)(NSString * _Nonnull, ...))appendingFormat{
    return ^(NSString *format, ...){
        va_list list;
        va_start(list, format);
        NSString *string = [[NSString alloc] initWithFormat:format arguments:list];
        va_end(list);
        NSString *result = [self stringByAppendingString:string];
        return result;
    };
}

- (NSString * (^)(NSString * _Nonnull, NSString * _Nonnull, NSStringCompareOptions))replacingOccurrences{
    return ^(NSString *target, NSString *replacement, NSStringCompareOptions options){
        return [self stringByReplacingOccurrencesOfString:target withString:replacement options:options range:NSMakeRange(0, self.length)];
    };
}


- (NSString * (^)(NSRange, NSString * _Nonnull))replacingCharacters{
    return ^(NSRange range, NSString *replacement){
        return [self stringByReplacingCharactersInRange:range withString:replacement];
    };
}

- (NSComparisonResult (^)(NSString * _Nonnull, NSStringCompareOptions))compareBy{
    return ^(NSString *value, NSStringCompareOptions options){
        return [self compare:value options:options];
    };
}

- (BOOL (^)(NSString * _Nonnull))equalTo{
    return ^(NSString *value){
        return [self isEqualToString:value];
    };
}

- (BOOL (^)(NSString * _Nonnull))hasPrefix{
    return ^(NSString *value){
        return [self hasPrefix:value];
    };
}

- (BOOL (^)(NSString * _Nonnull))hasSuffix{
    return ^(NSString *value){
        return [self hasSuffix:value];
    };
}

- (BOOL (^)(NSString * _Nonnull))contains{
    return ^(NSString *value){
        return [self containsString:value];
    };
}

- (NSRange (^)(NSString * _Nonnull, NSStringCompareOptions))rangeBy{
    return ^(NSString *value, NSStringCompareOptions options){
        return [self rangeOfString:value options:options];
    };
}

- (NSData * _Nonnull (^)(NSStringEncoding))encoding{
    return ^(NSStringEncoding value){
        return [self dataUsingEncoding:value];
    };
}

- (NSArray<NSString *> *(^)(NSString *))separatedBy{
    return ^(NSString *value) {
        return [self componentsSeparatedByString: value];
    };
}

- (NSArray<NSString *> * _Nonnull (^)(NSCharacterSet * _Nonnull))separatedBySet{
    return ^(NSCharacterSet *value) {
        return [self componentsSeparatedByCharactersInSet:value];
    };
}

@end



附:NSMutableString
@interface NSMutableString (Chain)

//- (void)appendString:(NSString *)aString;
@property(nonatomic, copy, readonly) NSMutableString * (^appending)(NSString *);

///- (void)appendFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
@property(nonatomic, copy, readonly) NSMutableString * (^appendingFormat)(NSString *format, ...);

///- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString;
@property(nonatomic, copy, readonly) NSMutableString * (^replacingCharacters)(NSRange, NSString *);

///- (NSUInteger)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange;
@property(nonatomic, copy, readonly) NSMutableString * (^replacingOccurrences)(NSString *, NSString *, NSStringCompareOptions);

///- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
@property(nonatomic, copy, readonly) NSMutableString * (^insertAtIndex)(NSString *, NSUInteger);

///- (void)deleteCharactersInRange:(NSRange)range;
@property(nonatomic, copy, readonly) NSMutableString * (^deleteCharacters)(NSRange);

@end
@implementation NSMutableString (Chain)

- (NSMutableString * (^)(NSString * _Nonnull))appending{
    return ^(NSString *value) {
        [self appendString:value];
        return self;
    };
}

- (NSMutableString * (^)(NSString * _Nonnull, ...))appendingFormat{
    return ^(NSString *format, ...){
        va_list args;
        va_start(args, format);
        NSString *string = [[NSString alloc] initWithFormat:format arguments:args];
        va_end(args);
        [self appendString:string];
        return self;
    };
}

- (NSMutableString * (^)(NSRange, NSString * _Nonnull))replacingCharacters{
    return ^(NSRange range, NSString *value) {
        [self replaceCharactersInRange:range withString:value];
        return self;
    };
}
                                                                                                    
- (NSMutableString * (^)(NSString * _Nonnull, NSString * _Nonnull, NSStringCompareOptions))replacingOccurrences{
    return ^(NSString *target, NSString *replacement, NSStringCompareOptions options) {
        [self replaceOccurrencesOfString:target withString:replacement options:options range:NSMakeRange(0, self.length)];
        return self;
    };
}

- (NSMutableString * (^)(NSString * _Nonnull, NSUInteger))insertAtIndex{
    return ^(NSString *value, NSUInteger index) {
        [self insertString:value atIndex:index];
        return self;
    };
}

- (NSMutableString * _Nonnull (^)(NSRange))deleteCharacters{
    return ^(NSRange range) {
        [self deleteCharactersInRange:range];
        return self;
    };
}

@end
附:NSMutableArray
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSMutableArray<ObjectType> (Helper)

@property(nonatomic, copy, readonly) NSMutableArray *(^addObject)(ObjectType);
@property(nonatomic, copy, readonly) NSMutableArray *(^addObjects)(NSArray<ObjectType> *);

@property(nonatomic, copy, readonly) NSMutableArray *(^insertAtIndex)(ObjectType, NSUInteger);
@property(nonatomic, copy, readonly) NSMutableArray *(^removeAtIndex)(NSUInteger);
@property(nonatomic, copy, readonly) NSMutableArray *(^removeObjects)(NSArray<ObjectType> *);
@property(nonatomic, copy, readonly) NSMutableArray *(^removeAll)(void);

@property(nonatomic, copy, readonly) NSMutableArray *(^replaceAtIndex)(ObjectType, NSUInteger);

@property(nonatomic, copy, readonly) NSMutableArray *(^sort)(SEL);

@end

NS_ASSUME_NONNULL_END
#import "NSMutableArray+Helper.h"

@implementation NSMutableArray (Helper)

- (NSMutableArray * (^)(id _Nonnull))addObject{
    return ^(id obj) {
        if (obj) {
            [self addObject:obj];
        }
        return self;
    };
}

- (NSMutableArray * (^)(NSArray<id> *))addObjects{
    return ^(NSArray<id> * value) {
        if (value) {
            [self addObjectsFromArray:value];
        }
        return self;
    };
}

- (NSMutableArray * (^)(id, NSUInteger))insertAtIndex{
    return ^(id value, NSUInteger index) {
        if (value) {
            [self insertObject:value atIndex:index];
        }
        return self;
    };
}

- (NSMutableArray * (^)(NSUInteger))removeAtIndex{
    return ^(NSUInteger index) {
        if (index < self.count) {
            [self removeObjectAtIndex:index];
        }
        return self;
    };
}

- (NSMutableArray * (^)(NSArray<id> *))removeObjects{
    return ^(NSArray<id> * value) {
        [self removeObjectsInArray:value];
        return self;
    };
}

- (NSMutableArray * (^)(void))removeAll{
    return ^(void) {
        [self removeAllObjects];
        return self;
    };
}

- (NSMutableArray * (^)(id, NSUInteger))replaceAtIndex{
    return ^(id value, NSUInteger index) {
        if (index < self.count) {
            [self replaceObjectAtIndex:index withObject:value];
        }
        return self;
    };
}

- (NSMutableArray * (^)(SEL))sort{
    return ^(SEL aSel) {
        [self sortUsingSelector:aSel];
        return self;
    };
}

@end

Swift 链式编程库: SwiftChain
另类实现点语法:Then

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