More Related Content
Similar to Cocoa勉強会#43-Blocksを使う (11)
More from Masayuki Nii (20)
Cocoa勉強会#43-Blocksを使う
- 4. もっともシンプルな例
! void (^proc1)(void) = ^(void){ NSLog( @"==proc1=="); };
! proc1;
! proc1();
proc1は変数、よって「void (^)(void)」は型
^がともかく「関数」ないしは「その始まり」
戻り値は^の左(この場合はvoid)
引数は^の右(この場合はなし)
•
•
•
proc1だけではエラーは出ないが実行もされない
参照するだけで呼び出されない
•
proc1()によって、{ ... }の部分を実行する
2010年11月26日金曜日
- 5. 引数があるBlocksの例
! 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
変数はproc2、型的なものは int(^)(id, int)
=より後は本体、最初に仮引数を定義
本体の定義には引数は不要
•
•
2010年11月26日金曜日
- 6. Block内外での変数と変更可能性
!
!
!
!
__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'
__block宣言した変数はBlocks内で書き込める
そうじゃないものは書き込みができない
•
2010年11月26日金曜日
- 7. 引数にBlocksをもつ関数を定義する
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 );
スケルトン
Blocksの引数の返り値はvoid
引数は「変数定義」と同じ形式
•
•
関数の利用時
最初に紹介した基本型の右側と同じ
•
2010年11月26日金曜日
- 8. 引数に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日金曜日
- 9. 関数定義と長過ぎる引数
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日金曜日
- 10. マクロ定義で見やすくする
#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日金曜日
- 11. 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 );
引数並び、Blocksの型を定義してしまう
引数並びをマクロで定義
戻り値を加えて型の定義
•
•
プログラム本体はちょっと整理した雰囲気になる
2010年11月26日金曜日
- 12. クラス定義で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日金曜日