起因
某日使用DKChainableAnimationKit
的時候發現可以如下寫程式碼:
view.animation.rotate(180).anchorTopLeft.thenAfter(1.0).rotate(90).anchorCenter.animanimation
無獨有偶。Masonry
其實也是這樣用的
make.right.equalTo(self.view).with.offset(-10);
原理
看了一下程式碼,其實就是通過一個實現了所有方法的Chaining Method Object
,每一個方法都返回一個`Block, 這個
Block返回型別為
Chaining Method Object,
Block`的引數為你想要傳入的引數型別。
@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
然後就可以了:
HostObject* hostObject = [HostObject new];
[hostOjbect getChainingMethodObject].doA.doC(@"Hi there!").doD(@"Hello",@[@1,@2]).doB(100).doA;
參考
原作寫於segmentfault 連結