block的使用淺析

1 block的基本概念

1.1 block的產(chǎn)生和用途

代碼塊Block是蘋(píng)果在iOS4開(kāi)始引入的對(duì)C語(yǔ)言的擴(kuò)展,用來(lái)實(shí)現(xiàn)匿名函數(shù)的特性,Block是一種特殊的數(shù)據(jù)類型,其可以正常定義變量、作為參數(shù)、作為返回值,特殊地,Block還可以保存一段代碼,在需要的時(shí)候調(diào)用,目前Block已經(jīng)廣泛應(yīng)用于iOS開(kāi)發(fā)中。Block實(shí)際上是OC語(yǔ)言對(duì)閉包的實(shí)現(xiàn),是帶有自動(dòng)變量值的匿名函數(shù)。Block既可以定義在函數(shù)內(nèi)部也可以定義在函數(shù)外部。只有在調(diào)用block的時(shí)候,block{}內(nèi)的代碼才會(huì)執(zhí)行。

1.2 閉包的概念

閉包就是一個(gè)函數(shù),或者一個(gè)指向函數(shù)的指針,加上這個(gè)函數(shù)執(zhí)行的非局部變量。閉包允許一個(gè)函數(shù)訪問(wèn)聲明該函數(shù)運(yùn)行上下文中的變量,甚至可以訪問(wèn)不同運(yùn)行上文中的變量。

1.3 block的聲明與定義

 int (^myBlock)(int) = ^(int num){

return num*num;

};

int 代表返回類型 ^代表的這是一個(gè)block

myBlock代表block的名字 (int)代表參數(shù)類型

(int num)代表形參的類型及名字

在定義block的時(shí)候一定不要忘記在最后加上分號(hào)

block是一個(gè)對(duì)象,內(nèi)部是一個(gè)結(jié)構(gòu)體,在創(chuàng)建block 的時(shí)候就把它的指針傳給了block,所以可以直接調(diào)用block塊

但是為了使用block方便,一般在定義block的時(shí)候會(huì)用typedef簡(jiǎn)化block如:typedef void(^myBlock)(int) ;

1.4 block的實(shí)質(zhì)

通俗點(diǎn)說(shuō),block是一個(gè)結(jié)構(gòu)體,它里面包含了函數(shù)指針以及block外部上下文變量等信息,這個(gè)函數(shù)指針指向的是在定義block時(shí)的代碼塊。

1.5 block最常使用的情況

block最常使用的方式:界面?zhèn)髦担换卣{(diào)

2 Block對(duì)變量的訪問(wèn)與修改

2.1 block對(duì)局部變量的訪問(wèn)與修改

(1) block1 = ^{
        NSLog(@"哈哈哈哈哈哈");
    };
    block1();

(2) NSInteger aaa = 100;
    block2 = ^{
        aaa++;    //會(huì)報(bào)錯(cuò)
        NSLog(@"aaa的值為%ld",aaa);
    };

(3)__block NSInteger aaa = 100;
    block2 = ^{
        aaa++;  
        NSLog(@"aaa的值為%ld",aaa);   //aaa = 101
    };

(4) NSInteger aaa = 100;
    block5 = ^{
        NSLog(@"aaa的值為%ld",aaa);//aaa = 100
    };
    aaa = 105;
    block5();

(5)__block NSInteger ddd = 10;
    block7 = ^{
        ddd = ddd +1;
        NSLog(@"ddd現(xiàn)在的值為%ld",ddd);
    };
    ddd = 100;
    block7();

通過(guò)(1)說(shuō)明block只有在調(diào)用的時(shí)候其內(nèi)部代碼才會(huì)執(zhí)行,不調(diào)用其內(nèi)部代碼不會(huì)執(zhí)行,通過(guò)(2)和(3)說(shuō)明block可以訪問(wèn)局部變量,但是不能對(duì)其進(jìn)行修改,如果要在block里面修改局部變量的值,那么要在局部變量前面加_ block修飾符 。通過(guò)(4)和(5)可以看出如果局部變量不加 block來(lái)進(jìn)行修飾,那么當(dāng)在block定義后block調(diào)用前修改局部變量的值,那么block里面的局部變量依然是block定義時(shí)的值(因?yàn)樵赽lock定義的時(shí)候就將局部變量的值傳給了block所指向的結(jié)構(gòu)體,所以局部變量的改變不會(huì)影響block里面的局部變量,但是block里面的局部變量也是不可修改的),如果局部變量前面加 _block修飾,那么當(dāng)在block定以后block執(zhí)行前對(duì)局部變量進(jìn)行修改,block里面的局部變量值也會(huì)進(jìn)行相應(yīng)的改變(因?yàn)橛胈_block聲明局部變量后,在block里面是把局部變量的指針傳給block指向的結(jié)構(gòu)體的,所以其值可以被改變)。

2.2block對(duì)全局變量的訪問(wèn)

(1)// 聲明全局變量global
int global = 100;
void(^myBlock)() = ^{
   NSLog(@"global = %d", global);
};// 調(diào)用后控制臺(tái)輸出"global = 100"
myBlock();
(2)// 聲明全局變量global
int global = 100;
void(^myBlock)() = ^{
 NSLog(@"global = %d", global);// 調(diào)用后控制臺(tái)輸出"global = 101"
};
global = 101;
myBlock();
(3)// 聲明全局變量global
int global = 100;
void(^myBlock)() = ^{
    global ++;
   NSLog(@"global = %d", global);// 調(diào)用后控制臺(tái)輸出"global = 101"
};
myBlock();

結(jié)論:block可以直接對(duì)全局變量進(jìn)行訪問(wèn)和修改(全局變量所占用的內(nèi)存只有一份,供所有函數(shù)共同調(diào)用,在Block定義時(shí)并未將全局變量的值或者指針傳給Block變量所指向的結(jié)構(gòu)體,因此在調(diào)用Block之前對(duì)局部變量進(jìn)行修改會(huì)影響B(tài)lock內(nèi)部的值,同時(shí)內(nèi)部的值也是可以修改的)

2.3 block對(duì)全局靜態(tài)變量的訪問(wèn)

(1)// 聲明靜態(tài)變量global
static int global = 100;
void(^myBlock)() = ^{
   NSLog(@"global = %d", global);// 調(diào)用后控制臺(tái)輸出"global = 100"
};
myBlock();
(2)// 聲明靜態(tài)變量global
static int global = 100;
void(^myBlock)() = ^{
    NSLog(@"global= %d", global);// 調(diào)用后控制臺(tái)輸出"global = 101"
};
global = 101;
myBlock();
(3)// 聲明靜態(tài)變量global
static int global = 100;
void(^myBlock)() = ^{
    global ++;
   NSLog(@"global = %d", global);// 調(diào)用后控制臺(tái)輸出"global = 101"
};
myBlock();

結(jié)論:block里面可以直接訪問(wèn)和修改靜態(tài)全局變量(因?yàn)樵贐lock定義時(shí)便是將靜態(tài)變量的指針傳給Block變量所指向的結(jié)構(gòu)體,因此在調(diào)用Block之前對(duì)靜態(tài)變量進(jìn)行修改會(huì)影響B(tài)lock內(nèi)部的值,同時(shí)內(nèi)部的值也是可以修改的)

3 block的使用方式

block的使用與代理很類似,代理是讓某個(gè)類滿足自己的某個(gè)協(xié)議,然后實(shí)現(xiàn)協(xié)議里面的方法。Block是自己在本類定義了一個(gè)代碼塊,但是在需要的時(shí)候才會(huì)去調(diào)用。下面是一個(gè)block使用的小列子:
業(yè)務(wù)需求是在一個(gè)封裝的view中點(diǎn)擊了tableView的某一行,然后通過(guò)block把這一行上的字符串傳出去進(jìn)行處理,下面是具體實(shí)現(xiàn):

view的.h文件:
typedefvoid (^ChooseViewClick)(NSString*);
@interfaceChooseView : UIView<UITableViewDataSource,UITableViewDelegate>
@property(nonatomic,copy)ChooseViewClick chooseClick;
@end

當(dāng)tableView的某一行被點(diǎn)擊時(shí):

- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self dismiss];
    NSString *str =_showArray[indexPath.row];
    if(self.chooseClick) {
       self.chooseClick(str);
    }
 }

在另一個(gè)控制器進(jìn)行處理

 _chooseView.chooseClick = ^(NSString *str)
  {
           _selectTag = 0;
            [btnsetTitle:str forState:UIControlStateNormal];
        };

4 block使用之避免循環(huán)引用

在使用block的時(shí)候要特別注意的是避免循環(huán)引用,循環(huán)引用指的是兩個(gè)對(duì)象都相互強(qiáng)引用了對(duì)方,從而導(dǎo)致誰(shuí)也釋放不了,引起內(nèi)存泄露問(wèn)題。最常見(jiàn)的分為兩種情況,一種是這個(gè)對(duì)象擁有這個(gè)block,但是在block塊里面又引用了這個(gè)對(duì)象本身,第二種是block是宿主的一個(gè)屬性,但是在block里面又訪問(wèn)了宿主的其他屬性。
第一種情況,block是self本身的一個(gè)屬性,在block里面又訪問(wèn)了宿主本身:

self.myblock = ^{
[self doSomething];
};

在這里會(huì)引起循環(huán)引用,解決辦法是用__weak修飾,正確代碼如下:

__weak typedef(self) weakSelf = self;
self.myblock = ^{
[weakSelf doSomething];
};

第二種情況,block是宿主本身的屬性,在block里面又訪問(wèn)了宿主的其他屬性:

self.myblock = ^{
[self.muArray removeAllObjects];
};    //引起循環(huán)引用

此時(shí)解決方案跟上面一樣,可以加__block 或者_(dá)_weak 來(lái)修飾,正確代碼如下:

__block typedef(self) weakSelf = self;
self.myblock = ^{
[weakSelf.muArray removeAllObject];
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,489評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,290評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,776評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,510評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,866評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,036評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,585評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,331評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,536評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,754評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,154評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,469評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,273評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,505評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容

  • 《Objective-C高級(jí)編程》這本書(shū)就講了三個(gè)東西:自動(dòng)引用計(jì)數(shù)、block、GCD,偏向于從原理上對(duì)這些內(nèi)容...
    WeiHing閱讀 9,867評(píng)論 10 69
  • Block使用場(chǎng)景,可以在兩個(gè)界面的傳值,也可以對(duì)代碼封裝作為參數(shù)的傳遞等。用過(guò)GCD就知道Block的精妙之處。...
    Coder_JMicheal閱讀 733評(píng)論 2 1
  • iOS代碼塊Block 概述 代碼塊Block是蘋(píng)果在iOS4開(kāi)始引入的對(duì)C語(yǔ)言的擴(kuò)展,用來(lái)實(shí)現(xiàn)匿名函數(shù)的特性,B...
    smile刺客閱讀 2,365評(píng)論 2 26
  • 1.1 局部變量 局部自動(dòng)變量,在Block中可被讀取。Block定義時(shí)copy變量的值,在Block中作為常量使...
    陳雨塵閱讀 2,953評(píng)論 4 31
  • 小女子一直相信不論多遠(yuǎn),老天總會(huì)把那個(gè)適合的人帶到自己身邊,所以不急不緩永遠(yuǎn)像個(gè)小女生。 遇不到讓自己心動(dòng)的人,不...
    駱駝是朵花閱讀 218評(píng)論 0 0