Objective C 鏈式調用

原由

某日使用DKChainableAnimationKit的時候發現能夠以下寫代碼:git

view.animation.rotate(180).anchorTopLeft.thenAfter(1.0).rotate(90).anchorCenter.animanimation

無獨有偶。Masonry其實也是這樣用的github

make.right.equalTo(self.view).with.offset(-10);

原理

看了一下代碼,其實就是經過一個實現了全部方法的Chaining Method Object,每個方法都返回一個`Block
, 這個Block返回類型爲Chaining Method ObjectBlock`的參數爲你想要傳入的參數類型。segmentfault

@interface ChainingMethodObject : NSObject
- (ChainingMethodObject * (^)(void))doA;
- (ChainingMethodObject * (^)(NSInteger i))doB;
- (ChainingMethodObject * (^)(NSString* str))doC;
- (ChainingMethodObject * (^)(NSString* str, NSArray* array))doD;
@end

@implementation ChainingMethodObject
- (ChainingMethodObject * (^)(NSInteger i))doB{
    return ^id(NSInteger i) {
        //do actual stuff related with B
        return self;
    };
}
...其餘方法相似
@end

一般狀況下,ChainingMethodObject都會有delegate存在,具體視實際運用狀況而定,如動畫庫DKChainableAnimationKit中,animation裏有個weak var view:UIView指向UIView從而對target View進行操做。動畫

@implementation ChainingMethodObject
- (id) initWithObject:(id)obj{
    self = [super init];
    _delegate = obj;
    return self;
}
@end
@interface HostObject()
ChainingMethodObject * _cObj;
@end
@implementation HostObject (ChainingMethodObject)
- (ChainingMethodObject *) getChainingMethodObject{
    if (!_cObj)
        _cObj = [[ChainingMethodObject alloc] initWithObject:self];
    return _cObj;
}
@end

而後就能夠了:code

HostObject* hostObject = [HostObject new];
[hostOjbect getChainingMethodObject].doA.doC(@"Hi there!").doD(@"Hello",@[@1,@2]).doB(100).doA;

參考

DKChainableAnimationKitget

Masonryanimation

原做寫於segmentfault 連接it

相關文章
相關標籤/搜索