一 、 什麼是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 葬花...