Click here to load reader
Upload
masayuki-nii
View
257
Download
1
Embed Size (px)
DESCRIPTION
Cocoa勉強会#43 2010/11/27 Blocksを使う 新居雅行
Citation preview
Blocksを使う
Masayuki Nii - nii@msykCocoa Study #43Nov 27, 2010
2010年11月26日金曜日
Agenda
Blocksとは
いろいろな場合の書き方
マクロと型定義でより見やすく
2010年11月26日金曜日
Blocks
iOS 4/Snow Leopardよりサポート
プログラム自体をデータとして扱う•プログラム自体を変数に代入•定義した場所と別の場所で実行他の言語では「クロージャ」• iOS/Mac OS Xではこの言い方はしていない
2010年11月26日金曜日
もっともシンプルな例
proc1は変数、よって「void (^)(void)」は型• ^がともかく「関数」ないしは「その始まり」•戻り値は^の左(この場合はvoid)•引数は^の右(この場合はなし)proc1だけではエラーは出ないが実行もされない•参照するだけで呼び出されないproc1()によって、{ ... }の部分を実行する
! void (^proc1)(void) = ^(void){ NSLog( @"==proc1=="); };! proc1;! proc1();
2010年11月26日金曜日
引数があるBlocksの例
変数はproc2、型的なものは int(^)(id, int)• =より後は本体、最初に仮引数を定義•本体の定義には引数は不要
! int (^proc2)(id, int) = ^(id str, int c){ ! ! for( int i=0 ; i < c; i++ )!{ ! ! ! NSLog( @"%@",str );! ! }! ! return 99;! };//!proc2(); --> error: too few arguments to block 'proc2'! int x = proc2( @"Song", 3 );! NSLog( @"x=%d", x ); //! xの値は99
2010年11月26日金曜日
Block内外での変数と変更可能性
__block宣言した変数はBlocks内で書き込める•そうじゃないものは書き込みができない
! __block int b = 100;! int c = 200;! void (^proc3)(void) = ^(void){ b=b+c; };! proc3();! NSLog( @"b=%d", b );! // bの値は300! proc3();! NSLog( @"b=%d", b );! // bの値は500
//!void (^proc3)(void) = ^(void){ b++; c++; }; --> error: increment of read-only variable 'c'
2010年11月26日金曜日
引数にBlocksをもつ関数を定義する
スケルトン• Blocksの引数の返り値はvoid•引数は「変数定義」と同じ形式関数の利用時•最初に紹介した基本型の右側と同じ
void function1( int a, void (^b)(id,int))! {! b(@"pack",a);}
:! function1( 3, ^(id x,int y) { NSLog(@"%@,%d",x,y); } );!! void(^f1)(id,int) = ^(id x, int y){ NSLog(@"%@,%d",x,y); };! function1( 3, f1 );
2010年11月26日金曜日
引数にBlocksを持つ関数(戻り値あり)
int function2( int a, int (^b)(id,int))!{! int i=b(@"pack",a);! return i;}
:function2( 3, ^(id x,int y) { return 4; } );!function2( 3, ^(id x,int y) { } );
//-->error: incompatible block pointer types initializing 'void (^)(struct objc_object *, int)', expected 'int (^)(struct objc_object *, int)'
function2( 3, int ^(id x,int y) { return 4; } ); //-->expected expression before 'int'
function2( 3, (int)^(id x,int y) { return 4; } ); //-->invalid conversion initializing integer 'int', expected block pointer
function2( 3, int(^)(id x,int y) { return 4; } ); //-->expected expression before 'int'
function2( 3, (int)(^)(id x,int y) { return 4; } ); //-->expected specifier-qualifier-list before ')' token
エラーになる場合
2010年11月26日金曜日
関数定義と長過ぎる引数
分け分からん…
void samplefunc( int, void (^)(NSString*, NSString*, NSArray*, NSMutableArray*,
NSMutableDictionary*, int, int));
void samplefunc( int x, void (^func)(NSString* z1, NSString* z2, NSArray* z3,
NSMutableArray* z4, NSMutableDictionary* z5, int s1, int s2)){ func(....);[z1 release]; }
:samplefunc( 3,
^(NSString* z1, NSString* z2, NSArray* z3, NSMutableArray* z4, NSMutableDictionary* z5, int s1, int s2){
[z1 release];});
2010年11月26日金曜日
マクロ定義で見やすくする
引数の並びを仮引数込みでマクロ定義する•それを利用して、スケルトン、インプリメンテーション、利用時、それぞれで利用する•スケルトンでは仮引数は無視されるので、指定してあっても問題ない
#define LONGPARAM (NSString* z1, NSString* z2, NSArray* z3, \! NSMutableArray* z4, NSMutableDictionary* z5, int s1, int s2)
void samplefunc2( int, void (^)LONGPARAM);void samplefunc2( int x, void (^func)LONGPARAM){}
:samplefunc2( 3, ^LONGPARAM{! NSLog( @"%@",z2 );});
2010年11月26日金曜日
Blocksの型定義
引数並び、Blocksの型を定義してしまう•引数並びをマクロで定義•戻り値を加えて型の定義プログラム本体はちょっと整理した雰囲気になる
#define PARAM (id x,int y)typedef void (^func1param)PARAM;typedef int (^func2param)PARAM;
:func2param f2p;f2p = ^PARAM{ ! NSLog(@"%@,%d",x,y);! return 6;};function2( 3, f2p );
2010年11月26日金曜日
クラス定義でBlocks
引数並びのマクロ定義と型の定義を行えば、クラスの定義もすっきり
#define BLOCKPARAM (id x, int y, NSString *s)typedef float(^MyBlock)BLOCKPARAM;
@interface TestClass : NSObject{! MyBlock f;}- (void) myMethod: (MyBlock)bf;@end
@implementation TestClass- (void) myMethod: (MyBlock)bf! {! }@end
2010年11月26日金曜日
マルチタスク
NSThreadでマルチタスク•引数で渡したBlocksの実行がなんかおかしい•とりあえずはあきらめたが…NSInvocationOperation/NSBlockOperationがある• NSOperationの派生クラスなので、単純に言えばNSThreadの「今風」な使い方が可能• Blocksで渡したプログラムを、別スレッドで実行できた
2010年11月26日金曜日
考察
APIにBlocksを使うものが出てきている• iOSのバックグランドタスクはこれしかない•避けて通れないJavaScriptほどの柔軟性はない•文字列変数からBlocks生成はできない文法がなんか腑に落ちるような落ちないような•パターンで学習するしかないかな~
2010年11月26日金曜日