用OC寫一個defer

defer

defer是Swift中比較常用的一種語法庙洼,defer中的代碼將會在當(dāng)前的代碼塊結(jié)束之后調(diào)用栏赴。正如文檔中所說:

You use a defer statement to execute a set of statements just before code execution leaves the current block of code. This statement lets you do any necessary cleanup that should be performed regardless of how execution leaves the current block of code—whether it leaves because an error was thrown or because of a statement such as return or break.

無論你的代碼塊是通過break退出還是return退出,你在defer中代碼都會得到執(zhí)行耿眉,簡單演示如下:

func processFile(filename: String) throws {
    if exists(filename) {
        let file = open(filename)
        defer {
            close(file)
        }
        while let line = try file.readline() {
            // Work with the file.
        }
        // close(file) is called here, at the end of the scope.
    }
}

cleanup

OC中也有類似的概念边翼,那就是黑魔法之一 __attribute__(cleanup(...))
cleanup用來修飾一個變量鸣剪,當(dāng)他的作用域結(jié)束组底,一般來講就是當(dāng)前的代碼塊執(zhí)行結(jié)束的時候,可以執(zhí)行一個指定的方法西傀。當(dāng)然斤寇,這個變量也可以是一個block。

__unused static void cleanUpBlock(__strong void(^*block)(void)) {
    (*block)();
}

- (void)cleanUp {
    __strong void(^attribute_cleanup_block)(void) __attribute__((cleanup(cleanUpBlock), unused)) = ^{
        NSLog(@"clean up");
    };
    NSLog(@"processing");
}
輸出結(jié)果

當(dāng)然我們也可以把上面的內(nèi)容變成一個宏方便我們使用:

#ifdef __GNUC__
__unused static void cleanUpBlock(__strong void(^*block)(void)) {
    (*block)();
}

#define OnBlockExit __strong void(^attribute_cleanup_block)(void) __attribute__((cleanup(cleanUpBlock), unused)) = ^
#endif

- (void)cleanUp {
    OnBlockExit{
        NSLog(@"Clean up");
    };
    NSLog(@"processing");
}

復(fù)數(shù)場景

還有一點(diǎn)要說的就是 Swift中的defer是可以疊加的拥褂,也就是說我也以寫出如下的代碼:


func cleanup() {
    defer {
        print("defer 1")
    }
    defer {
        print("defer 2")
    }
    defer {
        print("defer 3")
    }
    print("End")
}
cleanup()

控制臺會依次輸出:

End
defer 3
defer 2
defer 1

OC中由于上面的宏定義的block名稱相同娘锁,所以簡單對宏做了一點(diǎn)改動,將block的名稱摘了出來:

#define OnBlockExit(block_name) __strong void(^block_name)(void) __attribute__((cleanup(cleanUpBlock), unused)) = ^
- (void)cleanUp {
    OnBlockExit(block_1) {
        NSLog(@"OnBlockExit 1");
    };
    OnBlockExit(block_2) {
        NSLog(@"OnBlockExit 2");
    };
    OnBlockExit(block_3) {
        NSLog(@"OnBlockExit 3");
    };
    NSLog(@"End");
}

//控制臺輸出:
End
OnBlockExit 3
OnBlockExit 2
OnBlockExit 1

可以看出無論是 defer還是cleanup饺鹃,再添加“死亡回調(diào)”的時候都是按照棧的結(jié)構(gòu)添加的莫秆。

應(yīng)用

defer常用與需要配對出現(xiàn)的代碼,比如文件的打開與關(guān)閉悔详,加鎖與解鎖镊屎,ARC以外的對象,如CoreGraphics中對象的create與release等茄螃。

由于代碼較少缝驳,且網(wǎng)上也可以搜到很多類似的資料,這次就不提供源碼了归苍,謝謝大家支持 : )

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末用狱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拼弃,更是在濱河造成了極大的恐慌夏伊,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吻氧,死亡現(xiàn)場離奇詭異溺忧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盯孙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門鲁森,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人振惰,你說我怎么就攤上這事歌溉。” “怎么了报账?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵研底,是天一觀的道長。 經(jīng)常有香客問我透罢,道長榜晦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任羽圃,我火速辦了婚禮乾胶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朽寞。我一直安慰自己识窿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布脑融。 她就那樣靜靜地躺著喻频,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肘迎。 梳的紋絲不亂的頭發(fā)上甥温,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音妓布,去河邊找鬼姻蚓。 笑死,一個胖子當(dāng)著我的面吹牛匣沼,可吹牛的內(nèi)容都是我干的狰挡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼释涛,長吁一口氣:“原來是場噩夢啊……” “哼加叁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起枢贿,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤殉农,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后局荚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體超凳,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年耀态,在試婚紗的時候發(fā)現(xiàn)自己被綠了轮傍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡首装,死狀恐怖创夜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仙逻,我是刑警寧澤驰吓,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布涧尿,位于F島的核電站,受9級特大地震影響檬贰,放射性物質(zhì)發(fā)生泄漏姑廉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一翁涤、第九天 我趴在偏房一處隱蔽的房頂上張望桥言。 院中可真熱鬧,春花似錦葵礼、人聲如沸号阿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扔涧。三九已至,卻和暖如春赁严,著一層夾襖步出監(jiān)牢的瞬間扰柠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工疼约, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卤档,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓程剥,卻偏偏與公主長得像劝枣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子织鲸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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