大刘的 iOS 自学笔记

OC链式编程的一个实践

2020-05-13  本文已影响0人  大刘

所谓链式编程,基本都是调用一个方法的时候返回对象本身,然后可以继续调用方法。以OC为例:

@interface Person : NSObject

- (Person *)eat:(NSString *)food;
- (Person *)drink:(NSString *)water;
- (Person *)sleep:(NSInteger)hour;

@property (nonatomic, weak, readonly) Person *(^makeFriend)(NSString *name);
@property (nonatomic, weak, readonly) Person *(^learn)(NSString *name);

@end
#import "Person.h"

@implementation Person

- (Person *)eat:(NSString *)food {
    NSLog(@"eat %@", food);
    return self;
}

- (Person *)drink:(NSString *)water {
    NSLog(@"drink: %@", water);
    return self;
}

- (Person *)sleep:(NSInteger)hour {
    NSLog(@"sleep: %ld hours", (long)hour);
    return self;
}

- (Person * _Nullable (^)(NSString * _Nonnull))makeFriend {
    return ^Person *(NSString *name) {
        NSLog(@"make friend: %@", name);
        return self;
    };
}

- (Person * _Nullable (^)(NSString * _Nonnull))learn {
    return ^Person *(NSString *name) {
        NSLog(@"learn: %@", name);
        return self;
    };
}

@end
#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = Person.new;
        [[[p eat:@"兰州拉面"] drink:@"水"] sleep:3].learn(@"数学").makeFriend(@"路飞");
    }
    return 0;
}

不过OC使用中括号调用方式的链式编程写起来不如点语法舒服。从底层支持链式编程的语言当数用于Fluuter的Dart语言,直接obj..method1()..method2()..,这是从语言底层直接支持。 写这种代码,Swift要比OC有优势。

我们知道这种写法能做些什么呢?Masonry就是使用这种思想来做的。在实际的工作中,我的一个工作经历是,项目中使用的是全是OC,在对视图进行赋属性时往往是:

UIView *view = UIView.new;
view.backgroudColor = ...
view.frame = ..
...

当时我想是否可以用链式思想简化一些写法,哪怕只是语法糖,但仍然是一件有意思的事情,于是花了半天时间写了出来,但是由于OC对泛型的支持并不彻底,在用OC写时做了一点手脚,最后调用代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view addSubview:UIButton.new
     .dl_frame(CGRectMake(0, 0, 100, 100))
     .dl_backgroundColor(UIColor.redColor)
     .dl_titleColorForState(UIColor.whiteColor, UIControlStateNormal)
     .dl_titleForState(@"Click me", UIControlStateNormal)
     .dl_center(self.view.center)
     .dl_cornerRadius(8)
     .dl_clipsToBounds(YES)
     .dl_addTargetAction(self, @selector(buttonClick:), UIControlEventTouchUpInside)];
}

我这里用自己的名字“大刘 dl_”作为前缀和系统方法区分。这里 是源码代实现。

https://github.com/ACommonChinese/OCLinkSetProperty

上一篇下一篇

猜你喜欢

热点阅读