資源描述:
《block使用小結(jié)、在arc中使用block、如何防止循環(huán)引用.doc》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、引言使用block已經(jīng)有一段時間了,感覺自己了解的還行,但是幾天前看到CocoaChina上一個關(guān)于block的小測試主題:?【小測試】你真的知道blocks在Objective-C中是怎么工作的嗎?,發(fā)現(xiàn)竟然做錯了幾道,?才知道自己想當(dāng)然的理解是錯誤的,所以抽時間學(xué)習(xí)了下,并且通過一些測試代碼進行測試,產(chǎn)生這篇博客。Block簡介(copy一段)Block作為C語言的擴展,并不是高新技術(shù),和其他語言的閉包或lambda表達式是一回事。需要注意的是由于Objective-C在iOS中不支持GC機制,使用Block必須自己
2、管理內(nèi)存,而內(nèi)存管理正是使用Block坑最多的地方,錯誤的內(nèi)存管理?要么導(dǎo)致returncycle內(nèi)存泄漏要么內(nèi)存被提前釋放導(dǎo)致crash。?Block的使用很像函數(shù)指針,不過與函數(shù)最大的不同是:Block可以訪問函數(shù)以外、詞法作用域以內(nèi)的外部變量的值。換句話說,Block不僅實現(xiàn)函數(shù)的功能,還能攜帶函數(shù)的執(zhí)行環(huán)境。可以這樣理解,Block其實包含兩個部分內(nèi)容1.Block執(zhí)行的代碼,這是在編譯的時候已經(jīng)生成好的;2.一個包含Block執(zhí)行時需要的所有外部變量值的數(shù)據(jù)結(jié)構(gòu)。?Block將使用到的、作用域附近到的變量的值建
3、立一份快照拷貝到棧上。Block與函數(shù)另一個不同是,Block類似ObjC的對象,可以使用自動釋放池管理內(nèi)存(但Block并不完全等同于ObjC對象,后面將詳細說明)。Block基本語法基本語法在本文就不贅述了,同學(xué)們自學(xué)。Block的類型與內(nèi)存管理根據(jù)Block在內(nèi)存中的位置分為三種類型NSGlobalBlock,NSStackBlock,NSMallocBlock。·NSGlobalBlock:類似函數(shù),位于text段;·NSStackBlock:位于棧內(nèi)存,函數(shù)返回后Block將無效;·NSMallocBlock:
4、位于堆內(nèi)存。1、NSGlobalBlock如下,我們可以通過是否引用外部變量識別,未引用外部變量即為NSGlobalBlock,可以當(dāng)做函數(shù)使用。1234{????//createaNSGlobalBlock????float?(^sum)(float,?float)=^(float?a,?float?b){?56789????????return?a+b;????};?????NSLog(@"blockis%@",sum);?//blockis<__NSGlobalBlock__:0x47d0>}2、NSStackBl
5、ock如下:12345678910111213141516171819{????NSArray?*testArr=@[@"1",?@"2"];?????void?(^TestBlock)(void)=^{?????????NSLog(@"testArr:%@",testArr);????};?????NSLog(@"blockis%@",^{?????????NSLog(@"testArr:%@",testArr);????});????//blockis<__NSStackBlock__:0xbfffdac0>????
6、//打印可看出block是一個?NSStackBlock,?即在棧上,?當(dāng)函數(shù)返回時block將無效?????NSLog(@"blockis%@",TestBlock);????//blockis<__NSMallocBlock__:0x75425a0>????//上面這句在非arc中打印是?NSStackBlock,?但是在arc中就是NSMallocBlock????//即在arc中默認會將block從棧復(fù)制到堆上,而在非arc中,則需要手動copy.}203、NSMallocBlock只需要對NSStackBloc
7、k進行copy操作就可以獲取,但是retain操作就不行,會在下面說明Block的copy、retain、release操作?(還是copy一段)不同于NSObjec的copy、retain、release操作:·Block_copy與copy等效,Block_release與release等效;·對Block不管是retain、copy、release都不會改變引用計數(shù)retainCount,retainCount始終是1;·NSGlobalBlock:retain、copy、release操作都無效;·NSStack
8、Block:retain、release操作無效,必須注意的是,NSStackBlock在函數(shù)返回后,Block內(nèi)存將被回收。即使retain也沒用。容易犯的錯誤是[[mutableAarryaddObject:stackBlock],(補:在arc中不用擔(dān)心此問題,因為arc中會默認將實例化的block拷貝到堆上)