Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20120422i phonedeveloperworkshoppublished

2,888 views

Published on

  • Be the first to comment

20120422i phonedeveloperworkshoppublished

  1. 1. 「エキスパートObjective-C プ ログラミング」で始める Blocks入門 朔 洋一郎 (@saku2saku)
  2. 2. Blocksとは?BlocksとはiOS 4から利用できるようになったC言語に対する拡張機能です自動変数(ローカル変数)の値を伴った無名関数無名関数とは? その名のとおり名前を持たない関数 JavaのEventListenerやjQueryのコールバック関 数などを使っている人であれば分かり易いかも
  3. 3. 無名関数のJQuery例 $.ajax({ type: "POST", url: "some.php", data: "name=John&location=Boston", success: function(msg){ alert( "Data Saved: " + msg ); } });上記はJQueryでsome.phpに対して、POSTリクエストを送った際に成功した場合のコールバック定義の例です
  4. 4. Blocksの構文^<戻り値の型>(<引数のリスト>) {式};
  5. 5. Blocksの構文返り値や引数リストが無い場合には省略可能です ^void (int tmp) {    NSLog(@"blocks test %d", tmp); } または ^ (int tmp) {    NSLog(@"blocks test %d", tmp); }
  6. 6. Blocksの構文返り値や引数リストが無い場合には省略可能です ^int (void) {    return 2; } または ^int {    return 2; }
  7. 7. Blocksの構文返り値や引数リストが無い場合には省略可能です ^void (void) {    NSLog(@”blocks test”); } または ^{    NSLog(@”blocks test”); }
  8. 8. Blocks変数Blocksは関数ポインタのように変数に代入することも可能になります<戻り値の型>(^<Blocks変数名>)(<引数リスト>);
  9. 9. Blocks変数int型の変数を返し、int型の引数を一個取るBlocks変数blkを定義する場合int (^blk) (int) = ^int (int count) { return count +2; };// 呼び出し方blk(3);
  10. 10. Blocks変数 typedefを使ってBlocks変数の型を定義することも 可能ですtypedef <戻り値の型>(^<Blocks変数名>)(<引数リスト>);
  11. 11. Blocks変数typedefを使った例typedef void (^completeBlock_t)(NSData *data);completeBlock_t block_ = ^(NSData *data) { //hogehoge; };
  12. 12. Blocksって使えるの?これだけではわかりにくいですが使えます!どういう面で使えるのかよくわからないけど? 処理が分散しない デリゲートもいいけど、別メソッドで実装する 必要があるため、処理の記述場所が分散する GCDのコードを書く際に必要 Grand Central Dispatch(GCD)というマルチ スレッド処理の仕組みを使う際に使用
  13. 13. オマケ:GCDって?GCDはマルチスレッドプログラミングを抽象的に実装するための仕組み今回は特に触れませんが、本サンプルの参考書籍「エキスパートObjective-Cプログラミング」に詳しく説明されています 例えば、画像の非同期通信での描画などに役立ち ます
  14. 14. サンプルコードhttp://workshop.iphonework.biz/files/2012/05/ BlocksSample.zip
  15. 15. TIPS
  16. 16. TIPS自動変数のキャプチャ自動変数の代入自動変数の参照型の扱い
  17. 17. 自動変数のキャプチャint型のプリミティブ型はBlocksが定義された時点の値としてコピーされる int main() { int val = 10; const char *fmt = "val = %dn"; void (^blk)(void) = ^ { printf(fmt, val) }; val= 2; fmt = "These valudes were changed. val = %dn"; blk(); return 0; } 結果は val = 2と表示される
  18. 18. 自動変数への代入自動変数のキャプチャは先程のとおり、Blocks構文が出現した段階でとられますそこにBlocks内で値を上書きすることは基本的にはできません(以下はエラーになる) int main() { int val = 20; void (^blk)(void) = ^ { val = 2}; blk(); printf("val = %dn", val); return 0; }
  19. 19. 自動変数への代入それでも値の変更をしたい場合には「__block」指定子を使う必要があります _は2つ重ねています 以下の場合はOK int main() { __block int val = 20; void (^blk)(void) = ^ { val = 2}; blk(); printf("val = %dn", val); return 0; }
  20. 20. 自動変数の参照型の扱い参照型はプリミティブ型(int, float, etc)でないクラスを持つような型を指します(NSObject, etc)参照型の場合には変数にはそのポインタが入りますが、これに足してもBlocksの中で代入はできません int main() { NSMutableArray *array = [[NSMutableArray alloc] init]; void (^blk)(void) = ^ { array = [[NSMutableArray alloc] init]; }; blk(); return 0; }
  21. 21. 自動変数の参照型の扱い参照型の場合は代入はできませんが、その変数の持つメソッドを呼んで、内部状態が変更になるのはOKです int main() { NSMutableArray *array = [[NSMutableArray alloc] init]; void (^blk)(void) = ^ { NSObject *obj = [[NSObject alloc] init]; array = [array addObject: obj]; }; blk(); return 0; }
  22. 22. ご清聴ありがとうございました

×