iOS-Block

Block是一種匿名函數(shù),也是一種Objective-C對象券盅。

語法


^ 返回值 (參數(shù)列表) 表達式
^ int (int a) {return a+1}

返回值和參數(shù)列表都可以省略

^ 表達式
^{NSLog(@"abc")}

聲明


block可以作為一個臨時變量鞭执,也可作為方法上的參數(shù),更可以作為一個函數(shù)定義伴找。

// 臨時變量 - 
// 返回值類型 (^變量名) (參數(shù)列表) = 語法
int (^aBlock)(int) = ^ int (int a) {return a+1};
NSLog(@"%d", aBlock(10)); 

// 方法參數(shù) -
(返回值 (^) (參數(shù)列表)) 參數(shù)名
- (void)excute:(void (^) (int a))blk;

// 函數(shù) -
typedef 返回值類型 (^函數(shù)名) (參數(shù)列表)
typedef int (^MyBlock)(int a);
MyBlock blk;
- (void)excute:(MyBlock)blk;

作為變量和作為方法參數(shù)Block的格式有一點區(qū)別盈蛮,為了避免記憶上的麻煩,建議使用函數(shù)形式定義技矮。

局部變量


函數(shù)中的局部變量在block中使用時抖誉,其值不受后續(xù)代碼影響。

int a = 10;
void (^MyBlock)() = ^{
    NSLog(@"內(nèi)部 a=%d", a); // 輸出 10
    a = 30; // 編譯器報錯
};
a = 20;
MyBlock();
NSLog(@"外部 a=%d", a); // 輸出20

因為block在編譯時會轉(zhuǎn)化為普通的C語言代碼衰倦,使用了struct結(jié)構(gòu)袒炉。在block中使用變量a時,其實質(zhì)是在block中聲明了相同屬性的變量樊零,姑且稱之為copyA我磁,并且將a的值賦予了copyA。在block使用的實際上是copyA。a的值在聲明了block之后才發(fā)生改變夺艰,按代碼的編譯順序并不會影響copyA芋哭,因此輸出的值還是10。

__block


通常情況下block中不允許對外部局部變量重新賦值劲适,除非該變量是靜態(tài)局部變量楷掉、靜態(tài)全局變量或者成員變量。如果需要改變局部變量的值霞势,可以采用__block修飾符進行修飾烹植。

__block int a = 10;
void (^MyBlock)() = ^{
    NSLog(@"內(nèi)部 a=%d", a); // 輸出 20
    a = 30;
};
a = 20;
MyBlock();
NSLog(@"外部 a=%d", a); // 輸出30

究其原因,使用__block修飾符修飾的變量在編譯時愕贡,block會為其創(chuàng)建一個結(jié)構(gòu)體草雕,結(jié)構(gòu)體中保留了該變量的地址。在使用該變量時固以,實際使用的是指針的方式訪問墩虹,因此不管是在函數(shù)中或者是在block中改變該變量都會互相影響。

strong / copy


當(dāng)block被作為一個成員變量時憨琳,該使用strong還是copy呢诫钓?
在block轉(zhuǎn)換成結(jié)構(gòu)體實例時會使用到objc_retainBlock函數(shù),而該方法在runtime時實際上就是_Block_copy函數(shù)篙螟,因此使用copy即可菌湃。
使用copy方法會將block從棧上復(fù)制到堆上,因此當(dāng)棧上的block被廢棄時(超出作用域)還能繼續(xù)使用該block遍略。

循環(huán)引用


在block中使用某個對象時惧所,block會持有該對象,在內(nèi)部形成一個類似autorelease的對象绪杏。當(dāng)block作為局部變量時下愈,在內(nèi)部使用了self并不會引起循環(huán)引用。但當(dāng)block作為成員變量時蕾久,由于self持有了該block势似,而block又持有了self,就會導(dǎo)致循環(huán)引用腔彰,無法釋放內(nèi)存叫编。因此如果需要在block中使用某個對象,通常建議使用該對象的弱引用霹抛。

BLK blk = ^{
    NSLog(@"self=%@", self); // 不會造成循環(huán)引用
};
blk();
    
self.blk2 = ^{
    NSLog(@"self=%@", self); // 循環(huán)引用,編譯器警告
};
self.blk2();

__weak ViewController * weakSelf = self;
self.blk3 = ^{
    NSLog(@"self=%@", weakSelf); // 不會引起循環(huán)引用
};
self.blk3();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卷谈,一起剝皮案震驚了整個濱河市杯拐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖端逼,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朗兵,死亡現(xiàn)場離奇詭異,居然都是意外死亡顶滩,警方通過查閱死者的電腦和手機余掖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來礁鲁,“玉大人盐欺,你說我怎么就攤上這事〗龃迹” “怎么了冗美?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長析二。 經(jīng)常有香客問我粉洼,道長,這世上最難降的妖魔是什么叶摄? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任属韧,我火速辦了婚禮,結(jié)果婚禮上蛤吓,老公的妹妹穿的比我還像新娘宵喂。我一直安慰自己,他們只是感情好柱衔,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布樊破。 她就那樣靜靜地躺著,像睡著了一般唆铐。 火紅的嫁衣襯著肌膚如雪哲戚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天艾岂,我揣著相機與錄音顺少,去河邊找鬼。 笑死王浴,一個胖子當(dāng)著我的面吹牛脆炎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播氓辣,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼秒裕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钞啸?” 一聲冷哼從身側(cè)響起几蜻,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤喇潘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梭稚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颖低,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年弧烤,在試婚紗的時候發(fā)現(xiàn)自己被綠了忱屑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡暇昂,死狀恐怖莺戒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情话浇,我是刑警寧澤脏毯,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站幔崖,受9級特大地震影響食店,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赏寇,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一吉嫩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嗅定,春花似錦自娩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碎乃,卻和暖如春姊扔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梅誓。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工恰梢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梗掰。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓嵌言,卻偏偏與公主長得像,于是被迫代替她去往敵國和親及穗。 傳聞我的和親對象是個殘疾皇子摧茴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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

  • 前言 Blocks是C語言的擴充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,774評論 0 23
  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數(shù)埂陆、block蓬蝶、GCD尘分,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 9,843評論 10 69
  • Block是iOS開發(fā)中一種比較特殊的數(shù)據(jù)結(jié)構(gòu)猜惋,它可以保存一段代碼丸氛,在合適的地方再調(diào)用,具有語法簡介著摔、回調(diào)方便缓窜、編...
    飛魚灣閱讀 4,128評論 0 7
  • 《Objective-C高級編程》是一本有趣又難懂的書,全書就講了引用計數(shù)谍咆、Block禾锤、GCD三個概念,有趣是因為...
    kamous閱讀 55,272評論 22 206
  • 工具命令轉(zhuǎn)化C++xcrun -sdk iphoneos clang -arch arm64 -rewrite-o...
    iYeso閱讀 3,138評論 6 67