NSString*
目的のCメソッドに含まれるCスタイルの配列を渡すための最良の構文は何ですか? これが私が現在使用しているものです:
- (void) f:(NSString **) a {
}
- (void) g {
NSString* a[2] = {@"something", @"else"};
[self f:a];
}
NSString*
目的のCメソッドに含まれるCスタイルの配列を渡すための最良の構文は何ですか? これが私が現在使用しているものです:
- (void) f:(NSString **) a {
}
- (void) g {
NSString* a[2] = {@"something", @"else"};
[self f:a];
}
他の唯一のオプションは次のとおりです。
- (void) f:(NSString* []) a {
}
コンパイルすると同じです。「最高」についてはわかりませんが、このバージョンの読みやすさを好みます。渡したポインタが配列として使用されることを意図していると推測する方が簡単です。ポインターへのポインターは他の場所でさまざまな用途があるため(NSError**
iOS SDKで使用されるさまざまなパラメーターを参照)、この区別は役立ちます。
少し良いです:
- (void) f:(NSString *[]) a
それが明らかにするように、それは、NStringへの参照への参照ではなく、NStringへの参照の配列(参照によって渡される)を期待している。
ただし、これによってコンパイラの型チェックが変更される可能性はほとんどありませんNSString **
。問題なく合格できます。境界を追加する場合も同じです。
- (void) f:(NSString *[2]) a
ここで、コンパイラはおそらく2を無視します。呼び出し時と本文内の両方で、「コメント」を追加するだけです。(多次元配列を渡す場合は、最後のインデックスを除くすべてを指定する必要があります。)
補遺
マイク・ケスキノフによるプロンプト(コメントを参照)
ARCの更新
ARCの下では、質問の宣言は次のとおりです。
NSString* a[2] = {@"something", @"else"};
明示的な所有権修飾子がないものは、次のように扱われます。
NSString* __strong a[2] = {@"something", @"else"};
これは、文字列への強力な参照の配列です。変数自体へのポインター(この場合は配列へのポインター)が渡されるとき、コンパイラーは、指定された変数の所有権資格を知る必要があります。配列へのポインタの場合の執筆時点では、コンパイラにはデフォルトがないため、上記のこの回答の宣言は次のとおりです。
- (void) f:(NSString *[]) a
以下のコメントでMikeKeskinovによって報告されているように、エラーが発生します。明示的な所有権修飾子を挿入する必要があります。
- (void) f:(NSString * __strong []) a
その情報を使用して、コンパイラは配列内の文字列参照を自動的に処理する方法を知っています。f
コンパイラの本体では、必要に応じて参照を自動的に保持および解放NSString
します。
ARCおよび変数/ポインターへのポインターの詳細については、「ARCおよびNSErrorでのポインター間の所有権の問題の処理」および「__autoreleasing」を参照してください。
定数配列に使用
元の質問の一部ではありませんが、Objective-Cで文字列定数の配列を持つ手段として多くの人がC配列を使用していることは明らかです。この特定の使用については、以下を観察してください。
配列とパラメーターの型が文字列への定数参照の配列として宣言されている場合、配列要素は変更できません。
配列を静的にすると、関数で宣言されている場合でも、配列が1回だけ作成および初期化されるようになります。と
C配列に文字列リテラルのみが含まれている場合__strong
、文字列リテラルは不滅であるため、デフォルトの所有権修飾子は必要ありません。代わりに、__unsafe_unretained
修飾子を使用できます。配列内の参照は常に有効です。
これらはコードフラグメントを生成します:
static NSString * const __unsafe_unretained a[2] = {@"something", @"else"};
と:
- (void) f:(NSString * const __unsafe_unretained[]) a
NSString
そして、定数リテラルの定数配列という目標があります。コンパイラは、アレイを変更したり、冗長なメモリ管理呼び出しを挿入したりすることを許可しません。
最良の方法は、C スタイルの配列の代わりに NSArray を使用することです。