- 什么是Block變量捕獲
block變量捕獲就是在block內(nèi)部創(chuàng)建一個變量來存放外部變量- 什么是值捕獲
block將外部變量的值存放到了內(nèi)部新創(chuàng)建的一個變量中- 什么是指針捕獲
block將外部變量的指針存放到了內(nèi)部新創(chuàng)建的一個變量中- 會對全局變量捕獲嗎
不會對全局變量捕獲,只會對局部變量進行捕獲
問題1
int age = 10;
void (^captureBlock)(void) = ^{
NSLog(@"age is %d",age);
};
age = 20;
captureBlock();
問題:打印出來age是多少
正確答案:10
這是一道關(guān)于block的變量捕獲的問題瓮恭,如果對block變量捕獲不是很明白的話雄坪,很容易說出age是20的錯誤答案。在block還沒調(diào)用時屯蹦,block已經(jīng)對age的值捕獲了维哈,并在block內(nèi)部生成了一個age變量,將外部age的值賦值了自己生成的age登澜,這時block內(nèi)部的age的值已經(jīng)跟外部的沒有關(guān)聯(lián)了阔挠,所以當外部值改變時并不會影響到內(nèi)部的值。這種情況稱為block的值捕獲脑蠕。
在1-1可以看到购撼,在內(nèi)部已經(jīng)另外生成了一個age。
問題2
int age = 10;
static int height = 10;
void (^captureBlock)(void) = ^{
NSLog(@"age is %d,height is %d",age,height);
};
age = 20;
height = 20;
captureBlock();
問題:打印的age和height分別是多少
答案:age:10 height:20
這個問題對比上個問題多了個height變量谴仙,但是這個變量跟age是有區(qū)別的迂求,height是static變量。在運行時block對static局部變量的捕獲是指針捕獲晃跺,block中存放的是外部height變量的指針揩局,當外部的值改變時內(nèi)部值也會跟著改變。從2-1可以看出掀虎,在編譯以后main函數(shù)block中age是值傳遞谐腰,height是指針傳遞。2-2中block內(nèi)部也分別生成了int age和int *height用來接收外部的值涩盾。
為什么局部變量age是值傳遞而static修飾的局部變量是指針傳遞呢十气?
- 因為局部變量age在離開作用域時(就是離開大括號時)就會被釋放,如果block是個全局春霍,在其他作用域調(diào)用時砸西,如果age是指針傳遞(保存的是指針),這時block去調(diào)用age時址儒,age已經(jīng)離開作用域被釋放了芹枷,內(nèi)存已經(jīng)不存在了,這時就會報錯莲趣,存在訪問野指針的情況鸳慈。所以對于局部變量非static修飾時,block就會值捕獲喧伞。
- static修飾的局部變量其內(nèi)存會一直存在走芋,不會因為離開作用域而被釋放绩郎,所以當全局block在其他作用域調(diào)用時不會報錯。
//定義block類型
void(^block)(void);
void test(){
int age = 10;
static int height = 20;
//在block內(nèi)部訪問 age , height
block = ^{
NSLog(@"age is %d, height is %d",age,height);
};
age = 20;
height = 20;
}
//在main函數(shù)中調(diào)用
int main(int argc, const char * argv[]) {
test();
//test調(diào)用后,age變量就會自動銷毀,如果block內(nèi)部是保留age變量的指針,那么我們在調(diào)用block()時,就出現(xiàn)訪問野指針
block();
}
問題3
先聲明兩個全局變量age_和height_
int age_;
int height_;
age_ = 10;
height_ = 10;
void (^captureBlock)(void) = ^{
NSLog(@"age is %d,height is %d",age_,height_);
};
age_ = 20;
height_ = 20;
captureBlock();
問題:打印的age和height分別是多少
答案:age:20 height:20
這個問題和前面兩個問題又有所區(qū)別翁逞,這次age和height是一個全局變量肋杖,這次打印20的答案不是因為block的指針捕獲導致的。從3-1中可以看到挖函,在編譯以后block中并沒有生成一個age和height變量状植,所以block并沒有對age和height兩個變量進行捕獲。因為age和height是全局變量怨喘,在任何的作用域下都是能調(diào)用的津畸,所以block不會多此一舉對其進行捕獲,在內(nèi)部直接訪問就可以必怜。
block變量捕獲總結(jié)
- block只會對局部變量捕獲不會對全局變量捕獲
因為局部變量只能在本作用域內(nèi)才能被調(diào)用肉拓,block為了能在其他作用域內(nèi)調(diào)用只能對其捕獲。全局變量在任何地方都能被調(diào)用棚赔,所以不需要對其捕獲帝簇。 - 對static局部變量是指針捕獲徘郭,auto局部變量是值捕獲
在局部變量中不是static變量的默認為auto變量