2009-06-10 17 views
2

にNSMutableArrayのを渡す、私は関数を呼び出すと、それに配列を渡しています:私はココアで、この問題を持っている機能

[self processLabels:labels]; 

そして機能が通りです:

は、いくつかの私は、関数を呼び出す場所従い

- (void)processLabels:(NSMutableArray*)labs{ 
    labs = [[NSMutableArray alloc] init]; 
    [labs addObject:@"Random"]; 
.... 
} 

デバッグ、私は彼らがラボに追加されたときに新しいオブジェクトをラベルに追加されていないことを注意してください。私はラボを再初期化しているからですか?関数内でラベルをどのように再初期化できますか?

私はあなたがprocessLabelsに渡す前に、「ラボ」は初期化されなければならない、そしてそれが再初期化するべきではありません。..任意のヘルプは高く評価され、 おかげ

答えて

1

ステートメントlabs = [[NSMutableArray alloc] init];は、labsをメソッドのスコープ内の新しい配列を指すようにします。呼び出し側のポインタが新しい配列を指しているわけではありません。

// The caller 
NSMutableArray *labels;   // Don't initialize *labels. 
[self processLabels:&labels]; 

... 

- (void)processLabels:(NSMutableArray**)labs{ 
    *labs = [[NSMutableArray alloc] init]; 
    [*labs addObject:@"Random"]; 
    ... 
} 

processLabels:は、配列を割り当てますが、発信者がそれを解放する責任があるので、おそらく悪い考えです:あなたが呼び出し側のポインタを変更したい場合は

は、このような何かを行います。

あなたは、呼び出し元は、配列を所有する場合、あなたはこのようprocessLabels:を書くことができます:あなたがしたい場合

- (NSMutableArray*)processLabels { 
    NSMutableArray* labs = [[[NSMutableArray alloc] init] autorelease]; 
    [labs addObject:@"Random"]; 
    ... 
    return labs; 
} 

processLabels:はちょうどラベルのコレクションを返している場合

- (void)processLabels:(NSMutableArray*)labs{ 
    [labs removeAllObjects]; 
    [labs addObject:@"Random"]; 
    ... 
} 

あるいは、配列を解放する責任を負う呼び出し側は、autoreleaseを削除します。その場合、慣例では、メソッド名はallocまたはnewで始まるか、copyという単語が含まれている必要があります。

3

を を成功しなかったことにより、ByRefの使用してみました。

あなたが何らかの理由で事前に配列を初期化することはできません、あなたはprocessLabelsがそれを作成したい場合は、ポインタへのポインタを渡す必要があります。

[self processLabels:&labels]; 

及び方法は、に変更します

- (void)processLabels:(NSMutableArray**)labs{ 
    *labs = [[NSMutableArray alloc] init]; 
    [*labs addObject:@"Random"]; 
.... 
} 
1

あなたは(それが変更可能なの定義です)、それを変更することができるように可変配列を渡す必要がある - 可変配列、利用されるようにNSArrayのをオンにする:

NSMutableArray *writableArray = [NSMutableArray arrayWithArray:oldArray]; 

またはあなただけの空の可変配列にしたい場合:その後にそれを渡す

NSMutableArray *writableArray = [NSMutableArray array]; 

を一般的に話さ

2

、可変コレクションを渡さないためにpreferrableが、作業を実行する方法を提供します。それらの上に...

実際にあなたのコードに応答して、実際にあなたがそれを上書きしているときに、「ラボ」配列を関数に渡すことが目的であるのだろうかと思います。プロセス)。それはなぜですか?

+0

私はあなたに同意します。 voidを返す場合は、代わりに配列を返すのはなぜですか? – Abizern

1

既存の方法を修正することと、それについては悪い考え方の両方が正しいです。リファレンスによるパラメータへの保存は確かに有効であり、プレーンなCプログラムで頻繁に使用されますが、この場合は複雑さが増します。 Objective-Cでは、最初に戻り値を使用してオブジェクトを返すことが優先され、戻り値がすでに他のものを返すために使用されている場合にのみ、ポインタに戻って格納されます。これによってメソッドの読み込みと書き込みが容易になるだけでなく、他の言語(JavaやC#など)でよく使用される標準的なイディオムに準拠します。配列ポインタを割り当てて上書きすると、Clang Static Analyzerのようなツールで取り上げられる可能性の高いバグが明らかになります。

関連するノートでは、メソッドとパラメータのより良いネーミングも考慮する必要があります。 (あなたが作っている可変配列以外のソースから来ている "ラベル"を処理している場合、私はローカル変数 "labs"または "ラベル " - よりわかりやすい名前を使用します。メソッド名は、コードの読みやすさを大幅に向上させることができます。 Objective-Cでは、長い説明的なメソッド名が好まれます。 Xcodeはコード補完を行い、メソッド名はあいまいではないので、最終結果は通常より小さいの型指定です。

関連する問題