9

私はこのような方法を持っています:

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error
{
    @autoreleasepool {

          // Start processing.

          // Find some partway through error..
          if (error) {
              *error = [NSError errorWithDomain...];
              return NO;
          }

          // More processing.
    }
}

NSError が自動解放され、戻りが発生するとプールが排出されるため、これは壊れてクラッシュします。そのため、呼び出し元が取得するものは偽物になります。

メソッドを大幅に再設計できることはわかっているので、自動解放ブロックの外側にあるすべてのエラー ケースを収集しますが、この状況でエラー オブジェクトを処理する正しい方法があるかどうかを理解したいと考えています。ドメインとコードのプロパティは読み取り専用であるため、プールブロックの外で投機的な NSError を割り当て/初期化することはできません (メソッドが戻ると参照が消えると思います)。

メソッド宣言を次のように変更すると、問題が解決します。

- (void)processAThing:(id)thing error:(NSError * __strong *)error

しかし、その後、呼び出しサイトで非標準的な方法で大騒ぎする必要があります。これは、呼び出し元に内部 autoreleasepool の代償を払わせるにはひどいようです。

何かご意見は?ありがとう。

4

1 に答える 1

8

私は自分でこの問題を抱えていました。この場合、 の直前に新しい強い参照を宣言し、その一時参照からブロック@autoreleasepoolの直後にメソッド引数を設定するだけでよいと思います。@autoreleasepool

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error {
  __strong NSError *errOut = nil;
  @autoreleasepool {
    // do your stuff and set errOut instead of error
  }
  if (error) {
    *error = errOut;
  }
}

(ブラウザで入力され、コンパイラによるエラー チェックは行われません)

早すぎるリターンについては、ジャンプ ラベルを使用する必要があると思います (きれいでなくても)。

于 2013-01-23T21:50:27.237 に答える