2009-03-27 8 views
4

いくつかのコンテキスト:私は自分のFMDBコードのいくつかをクリーンアップしようとしています。 1つのテーブルに多数のカラムがあり、使用する必要のあるFMDBのメソッドは、NSStringのクラスメソッド+stringWithFormat:に似た、可変数の引数を必要とするメソッドです。NSArrayを+ stringWithFormatのような可変数の引数を必要とするメソッドに渡す方法はありますか?

例:テーブルのみ5列を持っている場合

[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" , 
@"hi'", // look! I put in a ', and I'm not escaping it! 
[NSString stringWithFormat:@"number %d", i], 
[NSNumber numberWithInt:i], 
[NSDate date], 
[NSNumber numberWithFloat:2.2f]]; 

は、それは悪くはないのですが、列は20+それは毛深い得るために開始したとき。

私がしたいのは、すべてのdb抽象化情報を持つ辞書を作成し、これらのクエリを動的に構築することです。私の質問は...どのようにObjective-Cでは、可変数の引数を期待してそのメソッドを作り出し、代わりにNSArrayを渡すのですか?

関連情報:

How can I write a method that takes a variable number of arguments, like NSString's +stringWithFormat:?

+0

残念ながら、数ヶ月前の同じ質問があります:http://stackoverflow.com/questions/431910/is-possible-send-a-array-in-obj-c-for-a-variable-arguments-function – Chuck

答えて

4

ちょうど配列を受け取り、更新を行いますFMDatabaseのカテゴリを作成する方が簡単かもしれません。それを実行するには、executeUpdateのほとんどをコピーする必要があります。

0

これはあなたが探している例ではないかもしれません。しかし、この場合、配列にあなたの文字列値を入れて、[theArray componentsJoinedByString:@ "、"]を使ってsql引数リストに変換します。

+0

これはSQLインジェクションの脆弱性を引き起こします。 –

1

NSInvocationは、あなたが探していることを行うかもしれないと思います。

setArgumentForIndexを呼び出すときは、args 0と1は暗黙的にObj-Cが埋め込まれているので注意してください。ここでarg 2は渡す最初の「本当の」argです。

+0

これは、ナットを割るためにハンマーを使うようなものです。これよりはるかに良い解決策があります。私はそれが解決策であるので、私はこの1つを投票するつもりはない、ただIMHOは非常に良いものではない。 – schwa

+2

ドキュメントから:「NSInvocationは、可変数の引数または共用体引数を持つメソッドの呼び出しをサポートしていません。 –

6

(編集:。。これはGCCの日に戻って働いていたそれは、Xcodeの4.6のようクランの下ではありません)


としてことを扱い、その後、C列に配列内のオブジェクトを取得します。可変引数リスト:

//The example input array 
int i = 42; 
NSArray *array = [NSArray arrayWithObjects: 
    [NSString stringWithFormat:@"number %d", i], 
    [NSNumber numberWithInt:i], 
    [NSDate date], 
    [NSNumber numberWithFloat:2.2f], 
    nil]; 

//The example destination (using NSString so anyone can test this) 
NSString *string = nil; 

//The intermediary C array 
NSObject **arrayObjects = malloc(sizeof(NSObject *) * [array count]); 
if (arrayObjects) { 
    //Fill out the C array. 
    [array getObjects:arrayObjects]; 

    //Use the C array as a va_list. 
    string = [[[NSString alloc] initWithFormat:@"%@ %@ %@ %@" arguments:(va_list)arrayObjects] autorelease]; 

    free(arrayObjects); 
} 

NSLog(@"string: %@", string); 

出力:

2009-03-26 20:10:07.128 NSArray-varargs[606:10b] string: number 42 42 2009-03-26 20:10:07 -0700 2.2 

あなたのケースでは、あなたが-[FMDatabase executeUpdate:arguments:]メソッドを使用します。

+0

私はcocos2d iphoneフレームワークで同じことをやろうとしていますが、配列データは正しくコピーされていますが、 '(va_list)dyn_va_list'をメソッドに渡しても、' va_list params; '有効なアドレスの変数とEXC_BAD_ACCESSを取得します。私は私の心を失っている、助けてください。ありがとう。 – Brenden

+0

この場合、クラスメソッドのva_startをva_copyに変更せずに動的va_listが機能しないことが判明しました。それが他のどのクラスでもうまくいくかどうかはわかりませんが、それは行きます。 (さらに読む:http://www.cocos2d-iphone。org/forum/topic/2547#post-65713) – Brenden

+0

Brenden:文字列に書式設定する必要があるオブジェクトの有効なC配列でない場合、それは機能しません。配列内の項目の例と書式文字列を含め、コードの抜粋を完全な形で質問してください。 –

関連する問題