iPhoneアプリ作成(18)オブジェクト間の変数の受け渡し方法
いくつもクラスを作ってプログラミングしていると、以下の内容が面倒になってきた。
・インスタンス変数を追加する際に、毎回、ヘッダファイルと実装ファイルに変数定義、@property文、@synthesize文
を追加する必要がある
・新規オブジェクトを作成する際に、生成先に変数の値をコピーしてやる必要がある
(又は生成元のオブジェクトのアドレスを渡してもいいが、あまり好きではない)
なにか良い方法はないか?
で、思いついたのが、下記の内容。
・インスタンス変数はすべて、Dictionary(コレクション)に入れてしまう。
そうすれば、新規のインスタンス変数を追加する際に、プロパティ定義なんか不要になる。
・生成元のインスタンス変数を、自動的に生成先のインスタンス変数にコピーする。
生成元で定義した内容を、生成先からいちいち参照するなんてことしなくて良いので、便利!!!
それを実現するために作ったクラスが「Parm」クラス。
このクラスを、作成するすべてのクラスに入れてやろうと思う。
下記の「Parm」クラスのサンプルは、簡略版です。実際にはロック、スレッド関係のメソッドを追加して使っています。
サンプルの内容
・ParmクラスをMyClassAとMyClasBに入れてやる
・mainはMyclasAを生成し10秒停止するだけ
・MyclasAはキー”test”で@”a”文字をインスタンス変数を定義し、MyclasBを生成する
・MyclasBは、自動的にキー”test”を読み込み、利用できるようになる
・生成元のオブジェクト(self)を渡すのに、initを改良したinit2を用意した。
・selfを受け取る変数の名前はsenderとしたが、これはdelphi言語で使われていた名前を流用してる
// // Parm.h #import <Foundation/Foundation.h> @interface Parm : NSObject { NSMutableDictionary *parmList; //変数リスト } @property (nonatomic,retain) NSMutableDictionary *parmList; -(id)init2:(id)sender; -(id)init; -(void)setParm:(NSString*)key value:(id)value; -(void)delParm:(NSString*)key; -(void)delAllParm; -(id)getParm:(NSString*)key; @end
// // Parm.m // ParmTest #import "Parm.h" @implementation Parm @synthesize parmList; //変数リスト -(id)init2:(id)sender{ self=[super init]; if(self) { parmList = [[NSMutableDictionary alloc]init]; if([[[sender parm]parmList]count]>0) //警告がでるが無視 //(実際に使うときは、parmメソッドを持つダミークラスをつくると警告を消せる) [parmList addEntriesFromDictionary:[[sender parm]parmList]]; //警告が出るが無視 [self setParm:@"sender"value:sender]; NSLog(@"%@",parmList); } return self; } -(id)init{ self=[super init]; if(self) { parmList = [[NSMutableDictionary alloc]init]; } return self; } -(void)dealloc{ [parmList release]; [super dealloc]; } -(void)setParm:(NSString*)key value:(id)value{ if(value != nil)[parmList setObject:value forKey:key]; } -(void)delParm:(NSString*)key{ if([parmList objectForKey:key] != nil)[parmList removeObjectForKey:key]; } -(void)delAllParm{ [parmList removeAllObjects]; } -(id)getParm:(NSString*)key{ return [parmList objectForKey:key]; } @end
// // MyClass.h #import <Foundation/Foundation.h> #import "Parm.h" @interface MyClassA : NSObject { Parm *parm; } @property (nonatomic,retain) Parm *parm; @end @interface MyClassB : NSObject { Parm *parm; } @property (nonatomic,retain) Parm *parm; @end
// // MyClass.m #import "MyClass.h" @implementation MyClassA @synthesize parm; -(id)init{ self=[super init]; if(self) { parm = [[Parm alloc]init]; //生成元がmain関数でオブジェクトではないため変数を受け取れない。そのため通常のinitで生成 [parm setParm:@"test" value:@"a"]; MyClassB *objB = [[MyClassB alloc]init2:self];objB=objB; //生成元のアドレス(self)を渡す } return self; } -(void)dealloc{ [parm release]; [super dealloc]; } @end @implementation MyClassB @synthesize parm; -(id)init2:(id)sender{ //生成元のアドレスをsender変数で受け取る self=[super init]; if(self) { parm = [[Parm alloc]init2:sender]; //生成元の変数を自動的に取り込む NSLog(@"test = %@",[parm getParm:@"test"]); } return self; } -(void)dealloc{ [parm release]; [super dealloc]; } @end
// // main.m // ParmTest #import <Foundation/Foundation.h> #import "MyClass.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; MyClassA *objA = [[MyClassA alloc]init]; [NSThread sleepForTimeInterval:10]; //10秒停止 [objA release]; [pool drain]; return 0; }
<実行結果>
2011-06-13 16:41:07.520 ParmTest[2462:903] { sender = ""; test = a; } 2011-06-13 16:41:07.524 ParmTest[2462:903] test = a