2

オブジェクトを返すメソッドを含むメイン アプリケーション デリゲートがあります。このアプリケーション デリゲートは、メイン スレッドで実行されます。

別のスレッドで実行される NSOperation もあります。アプリのデリゲート メソッドをメイン スレッドで呼び出せるようにしたいだけでなく、NSOperation スレッドから呼び出して、返されるオブジェクトを取得する必要もあります。私の最初の質問は、これを他のスレッドから呼び出すかどうかです...

id newObject = [[[UIApplication sharedApplication] delegate] myMethod];

...そのメソッドは NSOperation と同じスレッドで処理されますか、それともアプリケーション デリゲートと同じスレッド (メイン) になりますか?

myMethodまた、内部のコードが、操作スレッドまたはメイン スレッドによって一度に 1 回だけ呼び出されるようにしたいと考えています。アプリケーションデリゲートで NSLock インスタンス変数を作成して、次のようなことを行うことはできますか?

-(id)myMethod {
    [myLock lock];
    myObject = // Get or create my object to return
    [myLock unlock];
    return myObject;
}

ご協力いただきありがとうございます!

マイク

4

3 に答える 3

11

別のスレッドで何かを実行するコードを明示的に記述しない限り、すべてのメソッド呼び出しは、呼び出されたスレッドで直接実行されます。メソッド呼び出しに魔法はありません。スレッド化のための C 関数呼び出しとまったく同じセマンティクス/ABI を持つと考えることができます。

スレッド間の排他的アクセスを確保するために、ロック パターンは正常に機能します。

2 つの追加の無関係なメモ (非常に多くの人がつまずくため):

  • atomicスレッドセーフとはほとんど関係のないプロパティを宣言します。原子性は、正しい値ではなく、有効な値を取得することのみを保証します (違いがあります)。

  • 自動解放されたオブジェクトは、スレッド間で安全に渡されることはありません。送信スレッドでの明示的なものと、受信スレッドでのretain最終的なバランス調整が必要releaseです。

于 2009-10-27T17:50:37.847 に答える
3

NSOperationカスタム操作の作成の一部として必要なオブジェクトを単に提供するのではなく、スレッドでこの呼び出しを実行する必要がありますか?

その場合、パフォーマンスが重要でない限り、ロックを使用しないことをお勧めします。iPhone がサポートしている場合は、Grand Central Dispatch を使用してオブジェクトをスレッドに取得できます。

__block id newObject = nil;
dispatch_sync(dispatch_get_main_queue(), ^{
    newObject = [[[[UIApplication sharedApplication] delegate] myMethod] retain];
});

iPhone の場合、ヘルパー メソッドを作成したくなります。

- (void)createNewObject:(NSValue *)returnPtr {
    id newObject = [[[[UIApplication sharedApplication] delegate] myMethod] retain];
    *(id *)[returnPtr pointerValue] = newObject;
}

NSOperationそして、スレッドから次のように呼び出します。

id newObject = nil;
[self performSelectorOnMainThread:@selector(createNewObject:)
                       withObject:[NSValue valueWithPointer:&newObject]
                    waitUntilDone:YES];

実際にメイン スレッドで実行すると、暗黙のリスクが少なくなります。

于 2009-10-27T18:06:18.473 に答える