4

varargsのリストを調べていますが、リストの最後のオブジェクトに到達すると、常にBAD_ACCESSエラーが発生します。ARC関連の問題だと強く思います。

これが私がすることです:

-(NSString *)replaceTokensWithStrings:(NSString *)firstKey, ... {

        va_list _arguments;
        va_start(_arguments, firstKey);

        for (NSString *_currentArgument = firstKey; _currentArgument != nil; _currentArgument = va_arg(_arguments, NSString*)) {
            NSLog(@"%@", _currentArgument);
        }

        va_end(_arguments);

    return nil;
}

返される結果を保持するようにコンパイラに指示する必要va_argがありますが、このパラダイムをどこにどのように適用するかがわかりません。

更新1:これは私が私のメソッドを呼び出す方法です:

[@"Hello <firstname> <lastname>" replaceTokensWithStrings:
  @"firstname", @"Peter",
  @"lastname", "Smith", 
  nil];

更新2:質問を更新し、実際に間違ったことを明らかにするために作成したエラーを追加しました。以下の私の答えを参照してください。

4

6 に答える 6

3

私は完全に間違った道を進んでいました。問題は関数ではなく、関数の呼び出し方法でした(私の質問の例ではエラーを実行しなかったため、他の参加者はこれを知ることができませんでした)。

質問を更新しましたが、実際の問題は、NSStringのリストではなく5つのNSStringを渡し、最後のリストは通常​​のC文字列であったことです。

最後のC文字列が原因でBAD_ACCESS

悪い:

"Smith"

良い:

@"Smith"

今私は恥ずかしいです:-)

于 2012-07-20T07:39:42.673 に答える
1

Cにvarargsリストがある場合は常に、リスト内のアイテムの数を指定するか、最後のアイテムを識別する必要があります。言語はそれを行いません。これは、フォーマットステートメント(引数の数がフォーマットアイテムの数と一致する)または他のスキームを介して行うことができます。デフォルトのスキームは、呼び出しステートメントのパラメーター・リストをnilまたはで終了することNULLです。

のようなものの定義を見る場合NSArray arrayWithObjects、リストは常に。で終了する必要がありますnil

于 2012-07-19T12:29:25.623 に答える
1

私も一緒に働いてARCいます、私は次のパターンを使用しています、そしてそれは私にとってうまくいきます、私はそれで何の問題も経験したことがありません、それはあなたを助けるかもしれません:

- (void)workingWithDictionaries:(NSDictionary *)dictionary, ... {

    va_list _arguments;
    va_start(_arguments, dictionary);

    for (NSDictionary *_currentArgument = dictionary; _currentArgument != nil; _currentArgument = va_arg(_arguments, NSDictionary*)) {
        NSLog(@"%@", _currentArgument);
    }

    va_end(_arguments);
}
于 2012-07-19T16:20:16.273 に答える
1

私は今日同じ問題に直面しました。技術的にはARCとは関係がなく、保持することもできませんが、メソッド宣言/プロトタイプは次のようになります。

-(NSString *)replaceTokensWithStrings:(NSString *)firstKey, ... 
    NS_REQUIRES_NIL_TERMINATION;

このようにして、XcodeとCのプリプロセッサにMACROを使用するように指示し、常に'nil'で終了するように要求して、va_arg()が間違った位置にアクセスするのを防ぎます(BAD_ACCESS)

于 2014-01-02T22:00:20.717 に答える
0

ARCとは何の関係もありません。va_argは、リストの最後に到達したことを確認しないため、リストの後のメモリブロックへのポインタを返します。これは何でもかまいません。したがって、EXC_BAD_ACCESS。通常、引数の量を追加のパラメーターとして指定します。たとえば、次のようになります。

-(void *)replaceTokensWithNumberOfStrings:(int)numStrings strings:(NSString *)str1, ... {

次に、ループでを使用numStringsします。while

于 2012-07-19T12:21:53.007 に答える
0

va_argリターン(この例ではNSString *)からidタイプを期待していて、それがnil値を返す場合、クラッシュが発生します。これは、arcが返されたnilを保持しようとしているためです。

これを回避するには、割り当てている変数に__unsafe_unretainedを追加します。

于 2013-10-30T23:26:13.817 に答える