MacDev 板


LINE

Blog版 http://popcornylu.blogspot.com/2011/08/objective-c-block.html 在ios4推出後,出現了一個新的語言功能block。 這個功能其實有接觸多種程式語言的話, 會知道其實這個功能不算是Objctive-C特有的 別的語言可能叫做Lambda或是Closure, 這東西主要的特性是他除了是function外, 但是更紀錄了此function外部的環境。 也許有點抽象,我先舉個javascript的例子 var i = 2; var func = function(){ i = i * i;}; func(); // than i = 4 func(); // than i = 16 我們在中間定義一個function並且指派到func這個變數, 而在這邊可以用i這個外面的變數,因為在javascript中這樣的定義的就是一個closure, 他會記住外面有i這個變數, 所以之後我們連續呼叫兩次func, 則可以得到i是16這個結果 這個跟objective-c的block,或是別的語言的lambda,closure都是一樣的東西 相關的資料可以參考 http://goo.gl/aNd5 (Clousre - wikipedia) 裡面的介紹。 回到objective-c的block,當然這個好物當然要好好的利用一下, 這個東西最吸引人的地方就是可以帶不定數量的變數到function當中, 因為你只要環境中可以取得的都可以在function中使用 並且因為block(或是其他語言的closure)通常使用上都是anonymous function, 直接藏身在你的code當中, 因此可以讓程式碼更加精簡。 但是我覺得剛開始用block的時候,有時候會有知其然而不知其所以然的情況。 尤其是Objective-c最令人頭疼的記憶體管理的部份在block中更是複雜, 如果你不知道你的物件怎麼在block中去使用那會是一件危險的事情, 所以這個主題算是經驗分享文,來分享我現在對block的認知, 而當然ios有很多官方的API都支援block, 最有名的就是Grand Central Dispatch (GCD) 但是這篇不會介紹GCD, 我們把內容專注在block這個語言功能。 在講block怎麼用之前,容我先介紹C的function跟function pointer, 我認為在學block之前要有這個基本的認識比較好。 一來是block跟funtion有點相似,但是又有點不一樣, 知道function再來看block我覺得會比較透徹的瞭解 二來它們兩個定義的部份真的很像, 但是實作一個function跟block卻大不相同, 仔細想想兩個的差異絕對會對block更有深刻的感覺。 首先function相信大家都會實作function,這再簡單不過了 int plusone(int a) { return a+1; } 上面這裡定義了一個傳入參數是int回傳是int的function,這應該不用解釋太多了。 那function pointer呢? 可能開始有些人不是那麼熟悉了... int ooxx() { typedef int (*myfunc_type)(int a); myfunc_type myfunc = plusone; NSLog(@"return value = %d", myfunc(5)); } 這邊開始就要解釋了 第一行是我定義一個myfunc_type這個function pointer type, 而這個function type是傳入是int,回傳是int 而第二行是定義一個myfunc_type的變數,我讓他指到我們剛剛定義的plusone 而第三行我們就是去呼叫這個function pointer, 則他就會等同去呼叫plusone,並且帶入5。 如果上面的code你看懂了,恭喜你,block幾乎沒差太多,甚至更好用。 int ooxx() { typedef int (^myblock_type)(int a); myblock_type myblock = ^int(int a){ return a+1; }; NSLog(@"return value = %d", myblock(5)); } 第一行跟function pointer很像,原本function pointer是用*,但是block是用^ 第二行也是定義一個myblock_type的變數,但是不一樣的是他指到的是一個block, block的實作也是^開頭,緊接著是回傳type, 接著是傳入的參數,後面接上{....}就是block實作的內容啦。 就像前面所說的,block本身就是anonymous function的方式去定義, 有些時候anonymous function非常好用,例如定義event handler, 我們可以註冊event handler時,直接在後面寫event handler的邏輯, 可以很快的可以看到事件發生之後會要做哪些動作 不必像用function pointer或是delegate的方式需要把邏輯寫在另外一個function, 第三行(應該說第三個statement)就跟function pointer很像了,就是呼叫這個block。 當然block強大的地方就是block所包含的code可以使用外面的變數 例如下面的例子,temp是block外面所定義的, 但是我們可以直接拿來用 int ooxx() { int temp = 5; typedef int (^myblock_type)(int a); myblock_type myblock = ^int(int a){ return temp+1; }; NSLog(@"return value = %d", myblock(5)); } 但是值得注意的是,上面的code,在block中會把temp當作常數看待, 也就是說當定義block的時候,temp的值是5 即便我們在後來把temp改成1 但是得到的結果不會變, 這同樣也說明了一個特性, 那就是我們不能在block中,直接的修改(write)一個外部(區域)變數的值, 所以看下段code int ooxx() { int temp = 5; typedef int (^myblock_type)(int a); myblock_type myblock = ^int(int a){ temp++; return temp; }; NSLog(@"return value = %d", myblock(5)); } 這邊compile就會錯了,因為這邊不只是會讀temp的值,還會寫temp的值。 但是如果我們加上__block這個變數修飾.. 那此變數就可以在block中修改。 下面就是個例子 int ooxx() { __block int temp = 5; typedef int (^myblock_type)(int a); myblock_type myblock = ^int(int a){ temp++; return temp; }; NSLog(@"return value = %d", myblock(5)); } 以上就是常用的block的方法 事實上更常用的用法會是把block當參數傳到function, 這邊舉個GCD的例子, dispatch_async(queue, ^(void) { // some task here }); 這邊就是把一個block丟到queue中等待被背景執行, 而就是丟進一個傳入是void傳回是void的block 由於傳回是void,所以可以把^void(void){...}簡化成^(void){...} 在block的使用上常常會見到這種把block當參數的寫法,之後相信會漸漸的習慣。 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.239.120 ※ 編輯: popcorny 來自: 114.32.239.120 (08/30 23:07)
1F:推 iwayne:謝謝。...最近研究multi-thread,也常用到block 08/31 09:24







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP