block底層實現原理

來源:互聯網
上載者:User

標籤:

1、關於block的循環參考:

block屬性,一般用copy修飾;

1.1.如果沒有對block進行copy操作,block就儲存於棧空間

1.2.如果對block進行copy操作,block就儲存於堆空間---強引用

1.3.如果block儲存於棧空間,不會對block內部所用到的對象產生強引用

1.4.如果block儲存於堆空間,就會對block內部所用到的對象產生強引用

注意1:由於使用了copy修飾,如果block中調用了block屬性的對象,就會造成循環參考

  為了避免循環參考,需要對對象進行若引用修飾:

1 ICKPerson *p = [[ICKPerson alloc] init];2 // 1、修飾方法13     //    __unsafe_unretained typeof(p) weakP = p;4 // 2、修飾方法25     __block typeof(p) weakP = p;6     p.testBlock = ^{7         [weakP run];8     };

 

2、關於block中變數的值:

2.1  如果變數沒有通過__block修飾,那麼block中的變數本質是值捕獲,在建立block的同時,是將變數的值傳入到block中,無論什麼時候調用,變數的值就是最初傳進去的值

1  int age = 10;2  void (^block)() = ^{ // 值捕獲3    NSLog(@"age=%d", age);// 列印是10;4  };5  age = 20;6  block();

 

2.2  如果變數通過__block修飾,那麼block中的變數實際傳遞的是變數的地址,在建立block的同時,是將變數的地址傳入到block中,在調用block的時候,其變數的值是當時變數的值(通過地址(指標)擷取到)。

1 __block int age = 1;2  void (^block)() = ^{ // 值捕獲3         NSLog(@"age=%d", age);// 列印是20;4   };5     age = 20;6     block();

3、關於block的內部實現:

        建立block的時候,內部是建立了對應的函數;

        在調用block的時候,是調用了之前封裝的函數。

 

4、關於block的應用:

 4.1.如何定義block

 1  1、// inline 2      // blockName:block變數名 3      // 傳回值類型(^變數名)(傳回值類型) 4      <#returnType#>(^blockName)(<#parameterTypes#>) = ^(<#parameters#>) { 5      <#statements#> 6      }; 7 void(^block)() = ^(){ 8         NSLog(@"block"); 9     };10  2、// name:Block類型別名11 typedef void(^MyBlock)()12  MyBlock myBlock = ^(){13   };

   4.2、調用block

1  block();2  myBlock();

 

  4.3、實戰練習:

    // 4.通訊錄Block使用:

    // 點擊儲存,通知連絡人重新整理表格,用代理

    // block:小弟 代理:打電話

    // block:先把重新整理表格的代碼儲存起來

    // 等使用者點擊了儲存按鈕的時候,調用Block

4.3.1、在標頭檔中(向其他檔案中傳遞資料的檔案)定義一個block:是否帶參數,根據需求確定

1 @class ICKAddViewController,ICKContact;2 typedef void(^ICKAddViewControllerBlock)(ICKContact *contact);3 @interface ICKAddViewController : UIViewController4 @property (nonatomic, strong) ICKAddViewControllerBlock contactBlock;5 @end

4.3.2、在擷取資料後,跳轉頁面之前,調用block,將資料傳遞過去

1 - (IBAction)addcontact {2     ICKContact *contact = [ICKContact contactWithName:self.nameFiled.text andPhone:self.phoneFiled.text];3     // 調用block4     if (self.contactBlock) {5         self.contactBlock(contact);6     }7     [self.navigationController popViewControllerAnimated:YES];8 }

4.3.3、在擷取(儲存、利用)資料的檔案中(拿到擷取資料的對象的時候)調用其block屬性,儲存block程式碼片段(實現特定功能的代碼)

 1 // 跳轉控制器時資料傳遞 2 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 3     ICKAddViewController *addVc = segue.destinationViewController; 4     // 聲明block 5     addVc.contactBlock = ^(ICKContact *contact){ 6         [self.contacts addObject:contact]; 7  8         // 儲存資料 9         NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];10         NSString *path = [cache stringByAppendingString:@"contacts.data"];11         [NSKeyedArchiver archiveRootObject:self.contacts toFile:path];12         [self.tableView reloadData];13     };14 }

 

 

block底層實現原理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.