Block語法(1)

  1. 爲何要使用block。

咱們知道,對象與對象之間的通訊方式有如下三種:一、代理-協議;二、通知;三、block。三種方式都實現了對象之間的解耦合。其中不一樣就是:通知的通訊方式是1對多;代理、block的通訊方式是1對1.閉包

  2.Block的簡介。

  • Block是iOS4.0以後新增的一種語法結構,也成爲「閉包」。
  • SDK4.0新增的API大量使用了block
  • Block是一個匿名的函數代碼塊,此代碼塊能夠做爲參數傳遞給其餘對象。

  3. Block的使用

//int 是返回值;sumBlock 是Block變量類型;(int x,int y)括號裏面是參數。
int(^sumBlock)(int x,int y);

 

 1 //建立 myBlock
 2 - (void)createMyBlock {
 3     //定義block變量
 4     int(^sumBlock)(int x,int y);
 5     //實現block,而且賦值
 6     sumBlock = ^(int x,int y){
 7         return x + y;
 8     };
 9     //聲明myBlock變量,全局{int(^myBlock)(int x,int y);}
10     myBlock = sumBlock;
11     NSLog(@"%d",myBlock(20,20));
12 }

  4. 建立Block

Block有如下4種方式:函數

 1 //Block是匿名函數,沒法經過函數名調用,因此單獨使用沒有意義
 2 //  1.無參數  無返回值--與直接打印數據是同樣的效果,無心義
 3     ^(){
 4         NSLog(@"無參數  無返回值");
 5     }();
 6     
 7 //  2.有參數 無返回值
 8     ^(int a,NSString* text){
 9         NSLog(@"%d \n %@",a,text);
10     }(10,@"有參數  無返回值");
11     
12 //  3.有返回值  無參數
13     NSString* a = ^(){
14         return @"無參數  有返回值";
15     }();
16     NSLog(@"%@",a);
17     
18 //  4.有參數  有返回值
19     //定義block變量
20     int(^sumBlock)(int x,int y);
21     //實現block,而且賦值
22     sumBlock = ^(int x,int y){
23         return x + y;
24     };
25     NSLog(@"%d",sumBlock(10,10));
26 }
1 //有參數 有返回值(返回結果是 6 )
2     int(^powefBlock)(int x,int y);
3     powefBlock = ^(int x,int y){        
4         return x * y;
5     };
6     NSLog(@" powef = %d",powefBlock(2,3));

  5. Block和變量

  • 變量按做用能夠分爲全局變量和局部變量。
  • block中可使用這兩種變量,可是有不一樣的管理機制。

引用局部變量編碼

  • block引用局部變量時候,改變量會做爲常量編碼到block塊中。
  • 局部變量須要使用__block修飾,才能在block中修改。
 1 //      若是在block 代碼內部,使用外部變量時,number會變爲常量
 2     int  number = 10;
 3     ^(){
 4     //number = 20; 直接報錯 ---不能夠修改,已經變爲常量
 5         NSLog(@"%d",number);
 6     }();
 7 
 8 //--在內部改變-
 9   //在變量前加__block 聲明便可
10     __block int  number_1 = 10;
11     ^(){
12         number_1 = 20;
13         NSLog(@"%d",number_1);
14     }();
  • 引用外部變量
#import <Foundation/Foundation.h>

@interface MyObject : NSObject
{    
    //block 引用外部 成員變量
    int _number;
}
- (void)log;

@end
 1 - (void)log {
 2    
 3 //      block 引用外部 成員變量
 4     _number = 99;
 5     NSLog(@"---%ld-- ",self.retainCount);    
 6 //  使用block 修飾obj 對象  這樣obj 在block中使用不會被retain。
 7 //  obj 不能擁有 self 的全部權   block不會持有self對象
 8     __block MyObject* obj = self;    
 9     ^(){
10         //    判斷 obj 是否存在
11         if (!obj) {
12             return ;
13         }
14         //經過obj 獲取成員變量;打印結果是 1 
15         int a = obj -> _number;
16         NSLog(@"---%d-- ",a);
17         NSLog(@"*****%ld**** ",self.retainCount);
18     }();
19     
20 }

   6. Block的內存管理

  • 在block裏面引用一個局部的Objective-C對象的時候,該對象會被retain。
  • 若是局部變量使用__block修飾,則不會被retain。 
 1 //--------引用外部obj對象的時候----------
 2 //不會被retain,即obj1.retainCount始終是1
 3 //__block NSObject* obj1 = [[NSObject alloc] init];
 4 //延時調用之後,obj1.retainCount會變爲2
 5     NSObject* obj1 = [[NSObject alloc] init];
 6     NSLog(@"%ld",obj1.retainCount);
 7     
 8     //延時調用
 9     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        
10         NSLog(@"%ld",obj1.retainCount);
11     });
  • block自己能夠像對象同樣copy和release
  • block建立後內存是分配在棧上,調用copy方法以後,將block移動到堆中。
  • 當block聲明爲全局變量時候,應該調用block的copy方法。

 

  7. 循環引用

  • 在block(點語法)裏面引用一個實例變量的時候,改實例變量會被retain。
  • 如上規則容易致使循環引用,形成內

歡迎讀者查閱,如若轉載,請標明出處。spa

相關文章
相關標籤/搜索