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 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); @endNS_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

OC链式封装进阶/终结篇(属性转为链式编程工具化实现)
文章图片
CodeHelper.dmg
附:NSString
#import 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 *(^separatedBy)(NSString *); ///componentsSeparatedByString @property(nonatomic, strong, readonly) NSArray *(^separatedBySet)(NSCharacterSet *); @endNS_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 *))separatedBy{ return ^(NSString *value) { return [self componentsSeparatedByString: value]; }; }- (NSArray * _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 NS_ASSUME_NONNULL_BEGIN@interface NSMutableArray (Helper)@property(nonatomic, copy, readonly) NSMutableArray *(^addObject)(ObjectType); @property(nonatomic, copy, readonly) NSMutableArray *(^addObjects)(NSArray *); @property(nonatomic, copy, readonly) NSMutableArray *(^insertAtIndex)(ObjectType, NSUInteger); @property(nonatomic, copy, readonly) NSMutableArray *(^removeAtIndex)(NSUInteger); @property(nonatomic, copy, readonly) NSMutableArray *(^removeObjects)(NSArray *); @property(nonatomic, copy, readonly) NSMutableArray *(^removeAll)(void); @property(nonatomic, copy, readonly) NSMutableArray *(^replaceAtIndex)(ObjectType, NSUInteger); @property(nonatomic, copy, readonly) NSMutableArray *(^sort)(SEL); @endNS_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 *))addObjects{ return ^(NSArray * 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 *))removeObjects{ return ^(NSArray * 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

【OC链式封装进阶/终结篇(属性转为链式编程工具化实现)】Swift 链式编程库: SwiftChain
另类实现点语法:Then

    推荐阅读