1、Block 本質(zhì)上是一個struct結(jié)構(gòu)體恋昼,在這個結(jié)構(gòu)體中看靠,最重要的成員是一個函數(shù)(當(dāng)然除函數(shù)外還有其他重要的成員)。
2液肌、在開始解析Block之前挟炬,首先來回顧一下Block的格式。Block相關(guān)的格式有2個:
(1)、Block對象的格式谤祖;
(2)婿滓、Block變量的格式;
3粥喜、對于Block對象凸主,它有幾種常見的格式:
(1)、一個完整的Block對象的格式如下:
比如這個Block對象:
可以發(fā)現(xiàn)额湘,完整的Block對象和函數(shù)的定義非常相似卿吐,比如這個函數(shù):
兩者之間的區(qū)別僅僅是:Block對象多了一個“^”符號,并且不需要像函數(shù)一樣指定函數(shù)名锋华;
(2)嗡官、在完整的格式中有一些項目是可以省略的,比如“返回值類型”毯焕。不管Block對象是否有返回值衍腥,這個項目都是可以省略的,省略之后纳猫,只要表達(dá)式中有return語句就會自動使用該返回值的類型婆咸,如果沒有return語句就會使用void類型。
在這種情況下芜辕,Block對象的格式就變成了:
所以上文(1)中的Block對象可以寫成這樣:
(3)擅耽、除此之外,如果Block對象不需要參數(shù)的話物遇,那么“參數(shù)列表”這個項目也是可以省略的乖仇,這時候Block對象的格式就變成了:
比如這樣的一個Block對象:
4、定義了Block對象之后询兴,還要定義Block變量來持有它乃沙,才能更方便地使用Block對象∈ⅲ回顧一下3(1)的函數(shù):
對于這種函數(shù)警儒,可以聲明這樣一個函數(shù)指針類型變量來使用它:
這時使用*funcPtr的就相當(dāng)于在使用func函數(shù)了。
同樣的眶根,對于3(1)中的Block對象蜀铲,也可以聲明這么一個Block變量:
這時使用block()的時候就相當(dāng)于在使用這個Block對象了。
對比函數(shù)指針和Block變量的聲明属百,可以發(fā)現(xiàn)兩者也是非常相似的记劝,區(qū)別僅僅是將*號換成^號。
5族扰、如果要將Block變量當(dāng)做參數(shù)來傳遞的話厌丑,每次使用都完整地定義它顯然是很麻煩的事定欧。比如想要在一個函數(shù)里使用Block變量類型的參數(shù),完整的定義方式應(yīng)該是這樣的:
這顯然是很繁瑣的怒竿,這時候就可以通過typedef來簡化變量:
那么這個函數(shù)就可以定義成:
這時就可以非常方便地使用Block變量了砍鸠。
6、回顧完Block 相關(guān)的格式耕驰,接下來開始來討論Block的實現(xiàn)爷辱。
在前文提到過,Block最重要的組成部分是一個函數(shù)朦肘,這也就意味著托嚣,大部分Block能實現(xiàn)的功能,其實使用函數(shù)也可以實現(xiàn)的厚骗。接下來就先來試一試要如何在不使用Block的情況下實現(xiàn)Block的功能。
思考這么一個問題:假設(shè)有兩個按鈕button1和button2兢哭,要求實現(xiàn)以下功能:
(1)领舰、按鈕有編號;
(2)迟螺、編號可修改冲秽;
(3)、點擊按鈕輸出自己的編號矩父。
7锉桑、首先簡單的方法可以通過使用兩個函數(shù)來實現(xiàn):
兩個函數(shù)分別對應(yīng)兩個按鈕的點擊,調(diào)用函數(shù)時把按鈕的編號作為參數(shù)傳進(jìn)去窍株,便能打印出對應(yīng)編號民轴。
看起來似乎能滿足功能了,但是這種方法的問題也是很明顯的:按鈕并不持有自己的編號球订,需要調(diào)用函數(shù)的時候才將編號傳進(jìn)去后裸。
這種方法顯然還不夠完善。
8冒滩、根據(jù)面向?qū)ο蟮乃伎挤绞轿⑹唬ㄟ^將按鈕抽象成類并把編號定義成按鈕類的實例變量是可以實現(xiàn)這個功能的。但是這里只想要使用普通C語言來實現(xiàn)开睡,那么可以這么處理因苹,把每個按鈕的編號定義成全局變量來進(jìn)行保存,修改的代碼如下:
這樣按鈕就“持有”了編號篇恒,實現(xiàn)了問題的3個要求扶檐。
9、回過頭來看一看問題胁艰,如果要使用Block來實現(xiàn)這3個要求的話蘸秘,代碼會是這樣的:
這段代碼所實現(xiàn)的功能官卡,和8的代碼所實現(xiàn)的功能其實就是一樣的了。
10醋虏、事實上寻咒,這兩段代碼幾乎就是等價的了,8的代碼幾乎就是9的代碼轉(zhuǎn)換成普通C語言后的樣子(注意“幾乎”這個字眼颈嚼,實際上5的代碼轉(zhuǎn)換成普通C語言后與4的代碼還是有不少差別的)毛秘。
而對于問題中所提的3個要求,其實就是Block的3個主要功能點:
(1)阻课、能截獲變量叫挟;
(2)、能截獲可變的變量限煞;
(3)抹恳、回調(diào)。