iOS學習之block

來源:互聯網
上載者:User

標籤:系統   c語言   二進位   pop   靜態變數   __weak   結束   font   ios   

Block是C語言的擴充功能。帶有自動變數(局部變數)的匿名函數。(不帶有名稱的函數)

非匿名函數:int func(int count);(聲明了名稱為func的函數)使用:int result =func(10);

匿名函數:

 

Block文法:

  1.   ^傳回值類型  參數列表    運算式
      1. ^int        ( int count)    {  return count+1};
  2. 省略傳回值:
      1. ^        ( int count)    {  return count+1};
  3. 省略傳回值和參數列表:
    1. ^        ()    {  return count+1};或者^{  printf(“1223”);}
  4. 將Block賦值為Block類型變數:

傳回值類型(^塊名)(參數類型)=^參數列表    運算式

Int    (^blk)    (int)            =^(int count){return count+1;};

 

 

按照調用函數的方式調用塊物件變數就可以了:
int result = myBlock(4); // result是 28

 

  1. 在函數參數和傳回值中使用block
  • 函數參數:void func(int (^blk)  (int)  ){

}

  • 傳回值:int(^func())(int){

Return  ^ (int count)    {  return count+1}
}

 2.使用typedef簡化(定義別名)

定義: typedef int (^blk_t)(int);

  • 原本:void func(int (^blk)  (int)  ){
  • 簡化:void func(blk_t blk)
  • 原本:int(^func())(int){
  • 簡化:blk_t func()

原本:typedef int (^MyBlock)(int, int);

int (^minusBlock) (int, int) = ^(int a, int b){

return a - b;

        };  

        int (^multiBlock) (int, int) = ^(int a, int b){

    

            return a * b;

        };

下面的代碼更簡潔

        MyBlock minusBlock = ^(int a, int b){

            return a - b;

        };

        MyBlock multiBlock = ^(int a, int b){

            return a * b;

        };

  • (1)在類中,定義一個Block變數,就像定義一個函數;
  • (2)Block可以定義在方法內部,也可以定義在方法外部;
  • (3)只有調用Block時候,才會執行其{}體內的代碼;

Block的幾個特性:

  1. 自動變數值的截獲

Int dmy=256;

Int val=10;

Const char *fmt=”val=%d\n”;

Void(^blk)(void)=^printf(fmt,val);};

Val=2;

Fmt=”these values were changed. Val=%d\n”;

blk();

Return 0;

}

輸出結果:val=10;

 

 

2.修改外部變數(_block說明符)

   //將Block定義在方法內部

    int x = 100;

    void (^sumXAndYBlock)(int) = ^(int y){

    x = x+y;

    printf("new x value is %d",x);

    };

    sumXAndYBlock(50);

出現編譯錯誤:error: Variable is not assigning (missing __block type)

這時候給int x = 100;語句前面加上__block關鍵字即可

__block int x = 100;

這樣在Block的{}體內,就可以修改外部變數了。

 

Block儲存域:

程式佔用記憶體分布的結構:

 

棧區(stack:由系統自動分配,一般存放函數參數值、局部變數的值等。由編譯器自動建立與釋放。其操作方式類似於資料結構中的棧,即後進先出、先進後出的原則。

堆區(heap:一般由程式員申請並指明大小,最終也由程式員釋放。如果程式員不釋放,程式結束時可能會由OS回收。

全域區/靜態區:顧名思義,全域變數和靜態變數儲存在這個地區。只不過初始化的全域變數和靜態變數儲存在一塊,未初始化的全域變數和靜態變數儲存在一塊。程式結束後由系統釋放。

文字常量區:這個地區主要儲存字串常量。程式結束後由系統釋放。

程式碼區:這個地區主要存放函數體的二進位代碼

int a = 0; // 全域初始化區

char *p1; // 全域未初始化區

main {

    int b; // 棧

    char s[] = "abc"; // 棧

    char *p2; // 棧

    char *p3 = "123456"; // 123456\0在常量區,p3在棧上

    static int c =0; // 全域靜態初始化區

    p1 = (char *)malloc(10);

    p2 = (char *)malloc(20); // 分配得來的10和20位元組的地區就在堆區

    strcpy(p1, "123456"); // 123456\0在常量區,這個函數的作用是將"123456" 這串字串複製一份放在p1申請的10個位元組的堆地區中。

    // p3指向的"123456"與這裡的"123456"可能會被編譯器最佳化成一個地址。

 

 

Block的使用:

 

1.Block傳值

將B介面的textField.text傳給A介面的Label

A頁面:RootViewControllers  B頁面:DetailViewControllers

B頁面:DetailViewController檔案

#import <UIKit/Uikit.h>

typedef void (^DetailBlock)(NSString *);//block取別名。並且在參數列表中將需要傳遞的參數寫形參

@interface DetailViewController : UIViewController

@property (nonatomic, copy) PassingValueBlock passingvalue;//設定block屬性(注意使用copy)

@property (weak, nonatomic) UITextField *inputTF;

@end

 

- (IBAction)BtnAction:(id)sender {    

    //判斷block是否為空白

    if (self. passingvalue) {

      self. passingvalue (self.inputTF.text);       

 

    }

    [self.navigationController popViewControllerAnimated:YES];

 

}//點擊按鈕到A介面

 

RootViewController.m

 

@property (strong, nonatomic) UILabel *textLabel;

-(void)handleButton: (NSString*)sender{

DetailViewController *detailViewController = [[DetailViewController alloc]init];

detailViewController.passingValue=^( NSString* str){

self. textLabel.text= str;}

[self.navigationController pushViewController:detailViewController animated:YES];

}

 

2.Block避免循環參考

由於我們很多行為會導致Block的copy,而當Block被copy時,會對block中用到的對象產生強引用(ARC下)或者引用計數加一(non-ARC下)。

如果遇到這種情況:

@property(nonatomic, readwrite, copy) completionBlock completionBlock;

self.completionBlock = ^ {

        if (self.success) {

            self.success(self.responseData);

        }

    }

};

對象有一個Block屬性,然而這個Block屬性中又引用了對象的其他成員變數,那麼就會對這個變數本身產生強應用,那麼變數本身和他自己的Block屬性就形成了循環參考。在ARC下需要修改成這樣:

@property(nonatomic, readwrite, copy) completionBlock completionBlock;

__weak typeof(self) weakSelf = self;

self.completionBlock = ^ {

    if (weakSelf.success) {

        weakSelf.success(weakSelf.responseData);

    }

};

注1:iOS4.3之前版本就用__unsafe_unretained替代__weak

注2:如果是non-ARC環境下就將__weak替換為__block即可

 

iOS學習之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.