1、block的特點:
block是C語言;
block是一種數據類型、可以當做參數,也可以用做返回值
block是預先準備好的代碼塊、在需要的時候調用,(需要好好理解“需要時”);
2、定義block
3、block引用外部變量
在定義block時,如果使用了外部變量,block內部會默認對外部變量做一次copy;
默認情況下,不允許在block內部修改外部變量的值;
在外部變量聲明時,使用__block修飾符,則可以在block內部修改外部變量的值;
4、數組的遍歷&排序;
遍歷:enumerateObjectsUsingBlock:
所有的參數都已經準備到位,可以直接使用
效率比for高,官方推薦使用;
舉例:懶加載
enumerateObjectsUsingBlock遍歷:
[tempArrayenumerateObjectsUsingBlock:^(id_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {
NSDictionary*dict = (NSDictionary*)obj;
Heros*hero = [HerosherosWithDict:dict];
[ArrMaddObject:hero];
}];
for—IN遍歷:
for(NSDictionary*dictintempArray) {
Heros*heros = [HerosherosWithDict:dict];
[ArrMaddObject:heros];
}
排序:sortedArrayUsingComparator:
5.block在內存中的位置
?Block如果沒有引用外部變量
保存在全局區(qū)(MRC/ARC一樣)
?Block如果引用外部變量
ARC保存在堆區(qū);MRC保存在棧區(qū)必須用copy修飾block;
block快的存儲位置(block入口的地址)可能存放在3個地方:代碼區(qū)(全局區(qū))、堆區(qū)、棧區(qū)(ARC情況下會自動拷貝到堆區(qū)、因此ARC下只有兩個地方:代碼區(qū)和堆區(qū))。
?代碼區(qū):不訪問出去棧區(qū)的變量(如局部變量),且不訪問堆區(qū)的變量(如用alloc創(chuàng)建的對象)時,此時block存放在代碼區(qū);
?堆區(qū):如果訪問了處于堆區(qū)的變量(如局部變量),或堆區(qū)的變量(如用alloc創(chuàng)建的對象),此時block存放在堆區(qū)
6.block的循環(huán)引用
block對于其變量都會形成strong reference,對于self也會形成strong reference,而如果self本身對block也是strong reference的話,就會形成strong reference循環(huán),造成內存泄露。
解決方法:一般在block外面加一句—week typeof(self)weekSelf = self;防止self在block中應用計數加1,導致self和block循環(huán)引用無法釋放內存,造成內存泄露。