OCとSwiftがそれぞれチェーンプログラミングを実現することを記録する

4491 ワード

基本的な実装方法は,あるイベントが発生したときに実行する必要がある具体的な内容を閉パケット(swift)とblock(OC)で保存することである.イベントが発生したときに実行します.例ではNet.request().success({ }).error({ })のような
コードは一番下にあります(nonatomicこれらはすべて省略しました,,)
swiftの書き方はjavaなど他の言語とあまり違いません.具体的には、メソッドは現在のクラスの独自のインスタンスを返し、self/thisは、次のメソッドを呼び出し続けることができます.
OCは少し面倒ですが、やはり「[]」調の方法でmsgを送信するか、OCコードを書くのは初めてで、長い間適応できませんでした.OCはポイント構文を連続的に使用し、分析するとgetterメソッドを呼び出したはずです(実は後ろに他の書き方が見えますが、例では両方のメソッドが使われています.メッセージを送るのか呼び出すのか迷っていませんが、呼び出しメソッドを呼ぶのに慣れています).getメソッドはselfを返すと,「.」で他の属性にアクセスし続けることができる.[Clazz new].a.b, @property Clazz *a; @property Clazz *b;のように連続用「.」を実現できるようになったが,パラメータは伝達されなかった.
ブロックを用いてパラメータを実装する:@property Clazz *(^success) (int); @property Clazz *(^error) (int);は、[Clazz new].success(1).error(2)のようなものを実装することができるようになった.ここでは、2つのint属性を個別に宣言し、それぞれ入力された「1」および「2」:@property int successParam;を保存することができる.次にsuccessとerrorを初期化します.たとえば、次のようにします.
__weak typeof(self) wkSelf = self;
    [self setSuccess:^Clazz *(int param) {
        wkSelf.successParam = param;
        return wkSelf;
    }];
次にintパラメータをblockに変更すると,コードブロックをパラメータとして受信できる.たとえば、@property Clazz *(^success) (void(^aaa)(void));や、外伝のようなパラメータが必要な場合は@property Clazz *(^success) (void(^aaa)(int));など、怠け者でtypedefを書くのがおっくうです.パラメータを入力するだけですぐに実行すれば、前者を保存するために新しい属性を明記せずに、直接ブロックを呼び出しておけばいいのです.
[self setSuccess1:^Clazz *(void (^block)(void)) {
        //         
        block();
        //                  ,         
        //    @property void(^successParam1)(void);
        _successParam1 = block;
        return wkSelf;
    }];
具体コード:Swift
class A {
        fileprivate var successClosure: (() -> Void)?
        fileprivate var errorClosure: ((_ err: NSError) -> Void)?
        
        func success(_ closure: @escaping () -> Void) -> Self {
            successClosure = closure
            return self
        }
        
        func error(_ closure: @escaping (_ err: NSError) -> Void) -> A {
            errorClosure = closure
            return self
        }
        
        func request(url: String) -> A {
            print("    \(url)    ")
            ///    ,          , 
            DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(2)) {
                self.successClosure?()
            }
            
            DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(4)) {
                self.errorClosure?(NSError(domain: "      ", code: 1, userInfo: nil))
            }
            return self
        }
    }
次の操作を行います.
let a = A().request(url: "http://  .com").success {
                print("   ,,")
            }.error { (err) in
                print("   。。。。\(err.domain)")
            }
OC版:
//.h
@interface Clazz : NSObject

@property Clazz *(^success1) (void(^aaa)(void));
@property Clazz *(^success) (int);

- (Clazz *(^) (void(^)(NSError *)))error;

@end


//.m
#import "Clazz.h"

@interface Clazz ()

@property int successParam;
@property void(^successParam1)(void);

@end


@implementation Clazz

- (instancetype)init
{
    self = [super init];
    if (self) {
        __weak typeof(self) wkSelf = self;
        [self setSuccess:^Clazz *(int param) {
            wkSelf.successParam = param;
            return wkSelf;
        }];
        
        [self setSuccess1:^Clazz *(void (^block)(void)) {
            //         
            block();
            //                  ,         
            //    @property void(^successParam1)(void);
            //_successParam1 = block;
            return wkSelf;
        }];
    }
    return self;
}

- (void)test {
    self.success1(^{
        printf("asdas
"); }); } /// , - (Clazz *(^) (void(^)(NSError *)))error { return ^(void(^block)(NSError *)){ // , NSError *err = [[NSError alloc] initWithDomain:NSCocoaErrorDomain code:1 userInfo:nil]; block(err); return self; }; } @end
具体的な使い方は以下の通りです.
[Clazz new].success(1).success1(^{
        printf("success1 invoked not success
"); }).error(^(NSError *err){ NSLog(@"err: %@", err); });
      ,    ,      ,    ,    。       ,,,,