Block 學習筆記

2021-06-19 15:36:58 字數 3765 閱讀 8723

一 、 什麼是block?

a block is an anonymous inline collectionof code, and sometimes also called a 「closure」.

閉包是一種函式,它能夠讀取其它函式的內部變數。

block 也相當於內聯函式,執行速度快,簡單方便;

二、 為什麼要使用block ?

1.使用簡單、保持**在一起、蘋果推薦。。。。

2. block除了能夠定義引數列表、返回型別外,還能夠獲取被定義時的詞法範圍內的狀態(比如區域性變數),並且在一定條件下(比如使用__block變數)能夠修改這些狀態。此外,這些可修改的狀態在相同詞法範圍內的多個block之間是共享的,即便出了該詞法範圍(比如棧展開,出了作用域),仍可以繼續共享或者修改這些狀態。

3. 一般情況,

block

只能訪問變數,而不能修改變數的值。

而要想修改變數的值,有兩種方式,在定義變數的時候:

1).加static

關鍵字;

2).加__block

去修飾

三、 block 的使用

block 的簡單用法:

#import "blocktestviewcontroller.h"

#import #import @inte***ce blocktestviewcontroller ()

@property (nonatomic, copy) void (^myblock)();//使用block 作為屬性

@end

//block 定義

//無返回值 無參的block

void (^block)() = ^;

//無返回值 int 型別引數

void (^block1)(int) = ^(int n);

//無返回值 block作為引數

void (^block2)(void(^block)()) = ^(void(^block)());

//返回float block 作為引數 -- 計算block 方法執行所消耗的時間

float timeblock(void(^block)())

@implementation blocktestviewcontroller

@synthesize myblock;

- (id)initwithnibname:(nsstring *)nibnameornil bundle:(nsbundle *)nibbundleornil

return self;

}- (void)viewdidload

}));

self.myblock = ^;

self.myblock();

block();

block1(10);
block2(self.myblock);

[self executeblock:^completion:^(bool finished)

nslog(@"222222");

}];}//含有多個block 作為引數 的方法

/* ^表示是block 型別,

() 表示無參

void 表示返回值為空的block

*/- (void)executeblock:(void(^)())block completion:(void (^)(bool finished))completion

- (void)didreceivememorywarning

@end

如何在 block 中修改外部變數:

考慮到 block 的目的是為了支援並行程式設計,對於普通的 local 變數,我們就不能在 block 裡面隨意修改(原因很簡單,block 可以被多個執行緒並行執行,會有問題的),而且如果你在 block 中修改普通的 local 變數,編譯器也會報錯。那麼該如何修改外部變數呢?有兩種辦法,第一種是可以修改 static 全域性變數;第二種是可以修改用新關鍵字 __block 修飾的變數

__block int i = 0;

static int j = 0;

void (^block4)() = ^();

block4();

nslog(@"i = %d, j = %d", i , j);//i = 1; j = 2

block 陣列:

void (^blocks[2])(void) = ,      //注意逗號

^(void)

};

呼叫方式:
blocks[0]();

blocks[1]();

// blocks[2]();//當然也會有陣列越界

當然也會存在陣列越界的行為,如果在blocks[2]中我們即使生命了兩個但只實現了乙個block的實現,當呼叫block[1]的時候同樣也會發生陣列越界的行為;

四、 使用規則

block在使用過程中要避免引用環的出現, 如下例子,在block 中使用self 此時,block會retain  self 物件,使self的引用計數加1,從而會永遠無法執行dealloc 方法,因為在self 與block 之間產生了引用環;

[request setcompletionblock:^];解決方法:若引用self , 此時self 在block 中不會被計數 +1 

__block class *weakself = self;

[request setcompletionblock:^];

謹記!

block 是分配在 stack 上的,這意味著我們必須小心裡處理 block 的生命週期。比如如下的做法是不對的,因為 stack 分配的 block 在 if 或 else 內是有效的,但是到大括號 } 退出時就可能無效了:

void (^block3)(void) = 0;

if (true) ;

} else ;

}block3();

在block函式體中使用的例項變數將自動retained ,體會:目的是防止return時候沒有返回真正的帶有空間位址的變數;

eg:如果我們在objective-c的方法中使用block時,以下幾個和記憶體管理的事是需要額外注意的:

l 若直接訪問實體變數(instance variable),self的參考計數將被加1。

l 若透過變數訪問實體變數的值,則只變數的參考計數將被加1。

以下程式碼說明上面兩種情況,在這個假設instancevariable是實體變數:

1: dispatch_async (queue, ^);

5: id localvaribale = instancevariable;

6: dispatch_async (queue, ^);

未完待續。。。

Objective C學習筆記 block

一 基本概念 1 block的作用 block封裝了一段 在任何時候都可以使用。block的標誌是 2 block的特點 block可以作為函式引數或者函式的返回值,而其本身又可以帶輸入引數或返回值,和函式很像。二 基本使用 1 定義block變數 1 無形參 無返回值 void myblock 定...

Objective C學習筆記 Block

block 塊語法,本質上是匿名函式 沒有名稱的函式 block變數存放函式的實現,通過block變數能直接調?函式。標準c裡面沒有block,c語言的後期擴充套件版本,加?了匿名函式。c js swift等語?有類似語法,叫做閉包。block語法和函式指標很相似。block型別 int int b...

OC學習筆記之block

一 什麼是block block是oc中的乙個資料型別,但是它很特別,因為它是用來儲存一段 的 可以理解為把一段 賦值給block型別的變數 它和函式有點相似,它可以帶引數,可以有返回值,呼叫方式也一樣。二 定義乙個不帶形參沒有返回值的block main.m block created by 葬花...