iOS開發中Block的理解與使用


  1. 簡介
    • 我們可以把Block當做Objective-C的匿名函數。Block允許開發者在兩個對象之間將任意的語句當做數據進行傳遞,往往這要比引用定義在別處的函數直觀。另外,block的實現具有封閉性(closure),而又能夠很容易獲取上下文的相關狀態信息。
    • block是代碼塊,其本質和變量類似。不同的是代碼塊存儲的數據是一個函數體。使用Block,就可以像其他標准函數一樣,傳入參數,並得到返回值
      block的格式:
         a:Block的返回值類型,可以為空(void);
         b:Block對象名稱,可以理解為變量名;
         ^:塊的語法標記,聲明b為一個Block對象; 
         c:第一個參數類型
         d:第二個參數類型
         name1,name2:參數名;
         {}:Block代碼塊的主題部分。
     
         例: 
    int (^myBlock)(int,int) = ^(int num1, int num2) {
            return num1 + num2;
        };
        NSLog(@"%d",myBlock(5,4)); 
      • 打印結果:9
  2. 定義和使用
    1. 定義無返回值、無參數的Block
      • // 1.定義無返回值、無參的Block
            void (^block1)() = ^() {
                NSLog(@"無返回無參的Block");
            };
            block1();
    2. 定義無返回值、有參數Block
      • // 2.定義無返回值、有參數的Block
            void (^block2)(int) = ^(int a) {
                NSLog(@"%d",a);
            };
            block2(2);
    1. 定義返回值為OC對象的Block
      • // 3.定義返回值為OC對象的Block
            NSString *(^block3)(NSString *) = ^(NSString *string) {
                string = [NSString stringWithFormat:@"%@_%@",string,string];
                return string;
            };
            NSLog(@"%@",block3(@"我是字符串"));
    • 由以上可知,定義Block變量就相當於定義了一個函數,只有在調用block的時候才會執行其主體塊{}里面的代碼
  3. __block關鍵字的使用
    • 在Block的代碼塊里,是不能修改在外面定義的變量,並且在給block賦值的時候,已經對代碼塊里的變量做了值的拷貝(只讀不可修改)
      • int x = 5;
            int (^block4)(int) = ^(int y) {
                int z = x + y;
                return z;
            };
            NSLog(@"%d,%d",x +=5,block4(5));

        打印的值是10,10;

      • 分析:變量x在Block外定義的,在Block代碼塊編譯的時候,取的x的值為之前的5(不可修改)。因此即使執行x += 5的使x的值變為10,但Block代碼塊里的x依然是5,所以block(5)的值為5+5=10。
    • 在變量前添加__block關鍵字進行修飾后,此變量在Block代碼塊里的就是可更改的(可讀可寫),執行代碼時取變量最新的值。
      • __block int x = 5;
            int (^block4)(int) = ^(int y) {
                int z = x + y;
                return z;
            };
            NSLog(@"%d,%d",x +=5,block4(5));

        打印的值是10,15;

  4. 作為OC對象的屬性,實現對象之間的傳值
    • Block可以看做是一個變量,因此可以作為OC對象的屬性
    • 需求在ViewContrler的View上添加按鈕,點擊按鈕模態跳轉到FirstViewController視圖控制器,FirstViewController的View上又兩個按鈕,一個是直接dismiss模態跳轉到ViewController,一個是更改ViewController的背景色再dismiss模態跳轉回ViewController
    • 分析FirstViewController是有ViewController模態推出的視圖控制器,在FirstViewController里更改ViewController的背景色,這時就要做到反向傳值。
    • 實現步驟
      1. 1.在FirstViewController.h文件里,定義將block變量作為@property屬性
        • // 第一步定義, Block作為property屬性
          /*
           void: Block的返回值為空,即無返回值;
           colorBlock: Block的作為對象屬性時的屬性名;
           (UIColor *color): Block的參數是UIColor實例對象
           */
          @property (nonatomic, copy) void(^colorBlock)(UIColor *color);

           

      2. FirstViewController.m文件里,在按鈕點擊觸發的方法里給block傳參,調用block。
        • // 隨機生成的顏色
          UIColor *color = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
          // 第二步 給Block傳入參數color
          if (self.colorBlock) {
              self.colorBlock(color);
          }
          [self dismissViewControllerAnimated:YES completion:nil];
      3. 在ViewController.m 文件里,實例化FirstViewController對象的地方,執行block代碼塊。
        • FirstViewController *fvc = [[FirstViewController alloc] init];
          // 執行Block代碼塊
           fvc.colorBlock = ^(UIColor *color) {
              self.view.backgroundColor = color;
          };
    • 效果展示
      •          

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM