2

オブジェクトのメソッドをparamsで呼び出す必要があるように、NSInvocationOperationを作成しようとしています

- (void) getImages: (NSRange) bounds
{
    NSOperationQueue *queue = [NSOperationQueue new];
    NSArray * params = [NSArray arrayWithObjects:
          [[NSNumber alloc] initWithInt: bounds.location],
          [[NSNumber alloc] initWithInt: bounds.length]];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                   selector:@selector(loadImagesWithOperation)
                     object:params];

    [queue addOperation:operation];
    [operation release];

}

- (void) loadImagesWithOperation:(NSArray*)bounds {
 NSLog(@"loadImagesWithOperation");
}

このコードは EXC_BAD_ACCESS でクラッシュします。これに呼び出される関数の定義を変更すると

- (void) loadImagesWithOperation {
 NSLog(@"loadImagesWithOperation");
}

すべてがうまくなる。@selector(loadImagesWithOperation:)@selector(loadImagesWithOperation:bounds:)のような@selectorのコード ブロックで別の構文を使用しようとしましたが、成功しませんでした。

パラメータを使用してセレクタと関数を定義する正しい方法は何ですか?

ありがとう。

4

2 に答える 2

5

引数を取るa を定義する正しい方法は、各引数にSELコロン ( ":") 文字を使用することです。したがって、この場合、セレクターは次のようになります。

@selector(loadImagesWithOperation:)

したがって、NSInvocationOperationオブジェクトは次のように初期化する必要があります。

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
               selector:@selector(loadImagesWithOperation:)
                 object:params];

ああ、ちょっとしたメモとして、 in の初期化でメモリ リークが発生しNSArrayますgetImages:

NSArray * params = [NSArray arrayWithObjects:
      [[NSNumber alloc] initWithInt: bounds.location],
      [[NSNumber alloc] initWithInt: bounds.length]];

これにより、を使用しているため、既にretainCountのを持っているオブジェクトが追加されます。したがって、 に追加されると、メッセージが送信され、 が にインクリメントされます。1+allocNSArray-retainretainCount2

これNSArrayが割り当て解除されると、これらのオブジェクトは ではなく になるため、割り当て解除されretainCountませ10

この問題には、次の 3 つの解決策があります。

  1. autoreleaseに追加する前に、これらの各オブジェクトにメッセージを送信しますNSArray
  2. NSNumbernumberWithInt:クラス メソッドを使用して、自動解放されたNSNumberオブジェクトを取得します。
  3. NSNumberこれらのオブジェクトへの参照を作成し、それらを に追加してから、追加NSArray時にメッセージを送信し-releaseます。
于 2011-01-24T22:53:27.813 に答える
3

すべてがうまくなる。@selector(loadImagesWithOperation:) や @selector(loadImagesWithOperation:bounds:) などの @selector のコード ブロックで別の構文を使用しようとしましたが、成功しませんでした。

initWithTarget:selector:object:正確に 0 個または 1 個の引数を受け入れることができるセレクターを取ります。その 1 つの引数はオブジェクトでなければなりません。より多くの引数が必要な場合は、ブロックを使用するか、コードをリファクタリングします (残りのオブジェクトを含む配列を内部に渡すことは、可能性のある解決策です。そうです。そのコードで行っていることのようなものです (ただし、メモリ リークに注意してください)。

クラッシュは、あなたが示したコードとは無関係です。クラッシュを投稿します。

また、先頭に が付くメソッドはget、Cocoa/iOS では非常に特殊な意味を持ち、この種のパターンには使用されないことに注意してください。私はお勧めしloadImagesます。

于 2011-01-26T15:55:39.227 に答える