自從 iOS4 之后 block 橫空出世,它本身就封裝了一段代碼當(dāng)做變量,Apple 導(dǎo)入 block 語(yǔ)法之后就大幅改變了撰寫(xiě) Objective-C 語(yǔ)言的方法。
block 是Cocoa/Cocoa Touch Framework 中的匿名函式(Anonymous Functions)的實(shí)作。所謂的匿名函式,就是一段 具有物件性質(zhì)的程式碼,這一段程式碼可以當(dāng)做函式執(zhí)行,另一方面,又可以當(dāng)做物件傳遞;因?yàn)榭梢援?dāng)做物件傳遞,所以可以讓某段程式碼變成是某個(gè)物件的某個(gè) property,或是當(dāng)做 method 或是 function 的參數(shù)傳遞,就是因?yàn)檫@種特性,造成最常使用 block 的時(shí)機(jī),就是拿 block 實(shí)作 callback。
一、定義block
Xcode已經(jīng)幫我們準(zhǔn)備好了代碼塊,你只要輸入 inl就會(huì)出現(xiàn)一個(gè)非常全面的block。

image.png
按下回車(chē):

image.png
參數(shù)說(shuō)明:
- retuntype:返回值
- blockname:block的名字
- paramterType:參數(shù)類(lèi)型
- parmeters:參數(shù)
- statements:要執(zhí)行的代碼
例:我要寫(xiě)一個(gè)沒(méi)有返回值,名字叫MyBlock,沒(méi)有參數(shù),執(zhí)行的代碼叫NSLog(@"this is a blcok")的block。

image.png
注意:定義完了,不要忘記調(diào)用哦,block里面的代碼是預(yù)先準(zhǔn)備的代碼,編譯器走block的時(shí)候,是不會(huì)執(zhí)行里面的代碼的。需要你去調(diào)用。

image.png
如果你的調(diào)用寫(xiě)在按鈕的點(diǎn)擊事件里,那么你每點(diǎn)擊一次按鈕,就會(huì)打印一次“this is a block”
二、block作為對(duì)象的屬性
1、新建一個(gè)person類(lèi),在.h里面申明一個(gè)block。

image.png
2、在ViewController.m里,帶入person類(lèi)的頭文件。并且去實(shí)現(xiàn)已經(jīng)申明好的block。

image.png
三、block作為方法的參數(shù)
1、我們繼續(xù)來(lái)到person類(lèi),在里面聲明一個(gè)eat方法,用block作為參數(shù)。

image.png
2、我們?cè)俚?m里去實(shí)現(xiàn)這個(gè)方法。

image.png
3、好了??!方法申明了,也實(shí)現(xiàn)了。那么就輪到調(diào)用了,我們來(lái)到ViewController.m里來(lái)調(diào)用這個(gè)eat方法。

image.png
如果block本身要有參數(shù)我們?cè)撊绾文兀靠??

image.png

image.png

image.png
四、block作為返回值!!!(擴(kuò)展非常強(qiáng)!!)
1、我們還是用person類(lèi)來(lái)玩,能者多勞嘛。

image.png
2、這時(shí)我們要返回一個(gè)block,不是接收一個(gè)block,所以不是調(diào)用block,而是寫(xiě)好block里的代碼塊,然后返回給調(diào)用這個(gè)方法的對(duì)象。

image.png
3、重點(diǎn)來(lái)了我們來(lái)看看怎么實(shí)現(xiàn)的

image.png

image.png
給你們解釋一下為什么是p.look();,不是p.look;,前方高能~

image.png
記?。核械牟粠?shù),有返回值的方法。都可以用點(diǎn)語(yǔ)法,給點(diǎn)出來(lái)!!是不是想起什么了!!沒(méi)錯(cuò)就是get方法?。?/h3>
再看看block本身帶有參數(shù),作為返回值。
image.png
image.png
image.png
以上所有的叫響應(yīng)式編程?。。。òù?,通知這些都屬于響應(yīng)式編程)
響應(yīng)式編程的概念:
在網(wǎng)上流傳一個(gè)非常經(jīng)典的解釋“響應(yīng)式編程的概念”:在程序開(kāi)發(fā)中,a=b+c,
賦值之后b或者c的值變化后,a的值不會(huì)跟著變化。響應(yīng)式編程,目標(biāo)就是,如果b 或者c的數(shù)值發(fā)生變化,a的數(shù)值會(huì)同時(shí)發(fā)生變化。
還沒(méi)結(jié)束,block還能做到鏈?zhǔn)骄幊?。什么時(shí)鏈?zhǔn)骄幊蹋矣么a告訴你??!
五、block作為返回值且block本身帶有返回值。是不是有點(diǎn)繞,不要著急,我懂你,看??
1、步驟不變還是那三部曲,申明-->實(shí)現(xiàn)-->調(diào)用。下面申明方法
image.png
2、到.m里取實(shí)現(xiàn)它
image.png
3、我們來(lái)ViewController.m里調(diào)用它,順便解答為什么返回值要設(shè)定為Person。
image.png
有些小伙伴是不是覺(jué)得這個(gè)鏈?zhǔn)骄幊毯苎凼?,沒(méi)錯(cuò),Masonry這個(gè)框架就是利用了鏈?zhǔn)骄幊趟枷耄。。?/h1>
一個(gè)典型的Masonry的語(yǔ)句:
make.centerY.equalTo(self.view).offset(100);
在我心中Masonry這個(gè)框架可是鏈?zhǔn)骄幊痰囊粋€(gè)經(jīng)典代表作,非常值得參考和學(xué)習(xí),看完這篇文章后,我相信對(duì)你讀懂 Masonry 和 ReactiveCocoa(RAC)會(huì)有非常大的幫助?。。?/h1>
提示:我們拿到第三方框架后,不要只會(huì)使用它,而是要去理解它的編程思想,讓我們思考它們是怎么做到這些的!??!
六、天坑(循環(huán)引用)
上面五點(diǎn)寫(xiě)完了block的一生,下面我們就來(lái)看看循環(huán)引用?。?!
1、循環(huán)引用是怎么產(chǎn)生的?循環(huán)引用又是什么?
image.png
- 對(duì)象被強(qiáng)引用(strong)后,就不會(huì)被釋放,除非強(qiáng)引用者被釋放。
- 上面這張圖很好的解釋了循環(huán)引用,如果我們?cè)赽lock中調(diào)用self,那么就產(chǎn)生了循環(huán)引用。
- 循環(huán)引用就是,對(duì)象間相互強(qiáng)引用了對(duì)方,而導(dǎo)致雙方都無(wú)法被釋放。
3、循環(huán)引用帶來(lái)的危害
- 內(nèi)存泄漏、消耗變高
- APP性能變差,用戶(hù)體驗(yàn)不好
- 閃退,極可能導(dǎo)致用戶(hù)流失
2、如何防止循環(huán)引用?

image.png

image.png

image.png
響應(yīng)式編程的概念:
在網(wǎng)上流傳一個(gè)非常經(jīng)典的解釋“響應(yīng)式編程的概念”:在程序開(kāi)發(fā)中,a=b+c,
賦值之后b或者c的值變化后,a的值不會(huì)跟著變化。響應(yīng)式編程,目標(biāo)就是,如果b 或者c的數(shù)值發(fā)生變化,a的數(shù)值會(huì)同時(shí)發(fā)生變化。

image.png

image.png

image.png
一個(gè)典型的Masonry的語(yǔ)句:
make.centerY.equalTo(self.view).offset(100);
在我心中Masonry這個(gè)框架可是鏈?zhǔn)骄幊痰囊粋€(gè)經(jīng)典代表作,非常值得參考和學(xué)習(xí),看完這篇文章后,我相信對(duì)你讀懂 Masonry 和 ReactiveCocoa(RAC)會(huì)有非常大的幫助?。。?/h1>
提示:我們拿到第三方框架后,不要只會(huì)使用它,而是要去理解它的編程思想,讓我們思考它們是怎么做到這些的!??!
六、天坑(循環(huán)引用)
上面五點(diǎn)寫(xiě)完了block的一生,下面我們就來(lái)看看循環(huán)引用?。?!
1、循環(huán)引用是怎么產(chǎn)生的?循環(huán)引用又是什么?
image.png
- 對(duì)象被強(qiáng)引用(strong)后,就不會(huì)被釋放,除非強(qiáng)引用者被釋放。
- 上面這張圖很好的解釋了循環(huán)引用,如果我們?cè)赽lock中調(diào)用self,那么就產(chǎn)生了循環(huán)引用。
- 循環(huán)引用就是,對(duì)象間相互強(qiáng)引用了對(duì)方,而導(dǎo)致雙方都無(wú)法被釋放。
3、循環(huán)引用帶來(lái)的危害
- 內(nèi)存泄漏、消耗變高
- APP性能變差,用戶(hù)體驗(yàn)不好
- 閃退,極可能導(dǎo)致用戶(hù)流失
2、如何防止循環(huán)引用?

image.png
簡(jiǎn)單啊,不要在block中調(diào)用self就可以了嘛??!
等等。。我還沒(méi)說(shuō)完呢,刀放下。。有話好說(shuō)?。?!
盡量不要在block中使用self,避免不了的話,我們可以使用weak(弱引用),用weak替代strong,打斷循環(huán)引用!?。?/h5>
怎么用,給誰(shuí)用?
自己百。。。再送上一段代碼。槍放下先。。。

image.png
糾錯(cuò):
上面這段代碼呢,就算不用weak修飾呢,也不會(huì)引起循環(huán)引用哈,注意,self沒(méi)有強(qiáng)引用MyBlcok,即使MyBlock里強(qiáng)引用了self,也不會(huì)造成循環(huán)引用?。?!
正解:
先來(lái)一個(gè)循環(huán)引用

FC075098-5333-44D9-BC01-9F6F1AD1346C.png
再來(lái)干掉它

image.png
為什么block里面要默認(rèn)強(qiáng)引用呢?
其實(shí)不是block默認(rèn)為強(qiáng)引用
如果【block內(nèi)部】使用了【外部聲明的強(qiáng)引用】訪問(wèn)【對(duì)象A】,那么【block內(nèi)部】會(huì)自動(dòng)產(chǎn)生于一個(gè)【強(qiáng)引用】指向【對(duì)象A】
如果【block內(nèi)部】使用了【外部聲明的弱引用】訪問(wèn)【對(duì)象A】,那么【block內(nèi)部】會(huì)自動(dòng)產(chǎn)生于一個(gè)【弱引用】指向【對(duì)象A】。
補(bǔ)充:
還能使用__unsafe_unretained、__block修飾詞修飾被block持有的對(duì)象來(lái)打破循環(huán)
想要更加詳細(xì)的了解循環(huán)引用:點(diǎn)這里
咳咳,其實(shí)光年是距離。小伙伴們有沒(méi)有被我忽悠到呢?哈哈~