swiftにおける閉パケットとocにおけるblockの定義と用法の対比

5810 ワード

一.クローズドパッケージの紹介
  • 閉パケットは機能的自己包含モジュールであり、コードで伝達および使用することができる.Swiftの閉パッケージは、CおよびObjective-Cのblocksおよび他のプログラミング言語のlambdasと似ています.
  • 閉パケットは、そのコンテキスト内の任意の定数および変数の参照をキャプチャおよび格納することができる.これがいわゆる閉じてこれらの定数と変数を包んでいる、通称閉じている.Swiftは、取得中に関連するメモリ操作を管理します.
  • OCのblockは匿名の関数
  • です
  • Swiftの閉パッケージは特殊な関数
  • です.
  • blockおよび閉パケットは、しばしばコールバック
  • に使用される.

    二.blockの使い方を振り返る
    <1>. block書き方まとめ:
    block   :
          :
             (^block   )(block   )
    
         :
        ^(    ) {
            //      
        }
    
        //  
        int (^sumOfNumbers)(int a, int b) = ^(int a, int b) {
            return a + b;
        };
    

    <2>. blockは2つのインタフェース間の伝達値を実現する
        ①        .h      block
        //        NSString  
        typedef void (^newBlock)(NSString *);
        @interface NewViewController : UIViewController
        //   block  
        @property (nonatomic, copy) newBlock block;
        ②        .m      block
        - (void)viewWillDisappear:(BOOL)animated
        {
          [super viewWillDisappear:YES];
          if (self.block != nil) {
            self.block(@"  ");
          }
        }
    
        ③        .m          
        NewViewController *newVC = [[NewViewController alloc] init];
        //   block    
        __weak ViewController *weakSelf = self;
        newVC.block = ^(NSString *str){
            NSLog(@"%@,%@", weakSelf,str);
        };
    

    <3>. blockをパラメータとして遅延コールバック
  • ネットワーク要求のクラス
  • を定義する.
    @interface HttpTool : NSObject
    -(void)loadRequest:(void (^)())callBackBlock;
    @end
    @implementation HttpTool
    -(void)loadRequest:(void (^)())callBackBlock
    {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"           ,      :%@", [NSThread currentThread]);
            dispatch_async(dispatch_get_main_queue(), ^{
                callBackBlock();
            });
        });
    }
    @end
    
  • はネットワーク要求を行い、データを要求するとblockによりコールバック
  • を行う.
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.httpTool loadRequest:^{
            NSLog(@"    ,     .%@", [NSThread currentThread]);
        }];
    }
    

    三.クローズドパッケージの使い方
    <1>. 閉包の書き方まとめ:
          :(    )->(   )
          :         ,   ()->().         
    
         :
        {
            (  ) ->       in
            //     
        }
    
        let b = { (parm : Int) -> (Int) in 
           print(parm)
        }
    
        //  
        b(100)
    

    <2>.クローズド・パッケージの略語
  • 閉パケットにパラメータがなく、戻り値がない場合、inとinの前の内容は
  • を省略することができる.
        httpTool.loadRequest({
            print("     ", NSThread.currentThread());
        })
    
  • 末尾クローズドパッケージの書き方:
  • 閉パケットが関数の最後のパラメータである場合、閉パケットは()の後に
  • と書くことができる.
  • 関数に1つのパラメータしかなく、このパラメータが閉パケットである場合、()は
  • と書かなくてもよい.
        httpTool.loadRequest() {
            print("     ", NSThread.currentThread());
        }
    
        //         
        httpTool.loadRequest {
            print("     ", NSThread.currentThread());
        }
    

    <3>.ブロックの代わりに閉パケットを使用し、閉パケットをパラメータとして遅延コールバックを行う
  • ネットワーク要求のクラス
  • を定義する.
    class HttpTool: NSObject {
        func loadRequest(callBack : ()->()){
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
                print("    ", [NSThread.currentThread()])
    
                 dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    callBack()
                 })
            }
        }
    }
    
  • は、ネットワーク要求を行う、データを要求した後、閉パケットでコールバック
  • を行う.
        override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
            //     
            httpTool.loadRequest ({ () -> () in
                print("     ", NSThread.currentThread());
            })
        }
    

    <3>.インスタンス2、閉パケットのコールバック値
        //[weak self]:             
        override func touchesBegan(_ touches: Set, with event: UIEvent?) {
            delayMethod {[weak self] (re) ->() in
                print("$$$$$$$$$$$$$$$$$:\(re)%%%%%%%%%%%\(String(describing: self))")
            }
            delayMethod(comletion: {[weak self] (re)->() in
                print("********:\(re)*************\(String(describing: self))")
            })
        }
        
        //@escaping:    。              。                    ,     return        ,           。
        func delayMethod(comletion: @escaping (_ results: String,_ resultss:String) -> ()) ->(){
            //           
            DispatchQueue.global().async {
                Thread.sleep(forTimeInterval: 2.0)
                //      
                DispatchQueue.main.async(execute: {
                    print("      UI \(Thread.current)")
                    comletion("qwertyui","asdf")
                })
            }
        }
    
    

    <4>.2つのインタフェースの値を閉じる
  • 我々は、第2のインターフェースをクリックする後、第2のインターフェースをオフにし、第1のインターフェース<1>に値を伝達することを実現する.まず、動作
  • は、第2のインターフェースで閉パケットを宣言する.
    class NewViewController: UIViewController {
        //    
        typealias lewisCloser = (_ paramOne : String? ) -> ()
        //                 
        var customeCloser: lewisCloser?
        override func touchesBegan(_ touches: Set, with event: UIEvent?) {
            if(customeCloser != nil) {
                customeCloser!("          ")
            }
            self.dismiss(animated: true, completion: nil)
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
        }
    }
    

    <2>.最初のインタフェースで閉パケットを実現し,着用する値を取得する
    let vc = NewViewController()
    //    
    vc.customeCloser = {(cusValue) -> () in
          //cusValue       
          print("^^^^^^^^^^^^^^^^^^^^^:\(cusValue!)")
     }
    self.present(vc, animated: true, completion: nil)
    

    以上、swiftのクローズドパッケージとOCのblockの使い方を比較して、コメント交流を歓迎します!