1

[重複しない: 質問と既に与えられた回答をよく読んでください。私はすでにそれらを読みました]

私はその問題に直面しています-performSelector.ARCを使用したコンパイラでその警告が発生するため、メソッドを置き換える必要があります

performSelector は、そのセレクターが不明であるため、リークを引き起こす可能性があります

そのトピックについてさまざまな質問があることは承知しています。

また、その警告を回避するためのテクニックについても認識しています。
解決策として、最も推奨されるアドバイスは使用することであることがわかりましたが、dispatch_async(dispatch_get_main_queue(),^(void) { WHATEVER }); 私が知る限り、ディスパッチには次の実行ループでブロックの実行が必要であり、-performSelector(遅延なしで) すぐに実行されます。
なぜこのメンタルマスターベーション?認証に新しい Gamekit メソッドを使用していると想像してください。ゲーム キットは認証ブロック内にビュー コントローラーを送信して、ユーザーに何らかの操作 (ID の作成、ログインなど) を実行させることができます。ユーザーがそのView Controllerを表示したい場合は、ユーザーに警告すると便利です。それと他のことをするために、私はプロトコルを書いています。特に、そのメソッドは BOOL を返す必要があり- (BOOL)shouldLoadGameKitViewController: (UIViewController*) viewController;ます。-performSelector. ここがポイントです。メソッドがすぐに返されない場合、デリゲートから答えを得ることができません。
私はそれを実現するために NSInvocation を使用していますが、冗長ですが、他の方法はありますか?

[コードで更新]
現在呼び出しを使用していることに注意してください。スレッド チェック部分はまだ実装されていません。警告を与えた部分があるとコメントしました

- (void) dispatchToDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
    NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
    [invocation setTarget:self.delegate];
    if([self.delegate respondsToSelector: selector])
    {
        if(arg != NULL) {
            [invocation setArgument:&arg atIndex:2];      
            [invocation setArgument:&err atIndex:3];      

//          [_delegate performSelector: selector withObject: arg withObject: err];

        }else {
            [invocation setArgument:&err atIndex:2];      
//            [_delegate performSelector: selector withObject: err];

        }
        [invocation invoke];

    }
    else
        DLog(@"Method not implemented in the delegate");
}

[まだテストされていないソリューションの一種]

- (BOOL) dispatchToDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
    NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
    [invocation setTarget:self.delegate];
    BOOL result = NO;
    if([self.delegate respondsToSelector: selector])
    {
        if(arg != NULL) {
            [invocation setArgument:&arg atIndex:2];      
            [invocation setArgument:&err atIndex:3];      

//          [_delegate performSelector: selector withObject: arg withObject: err];

        }else {
            [invocation setArgument:&err atIndex:2];      
//            [_delegate performSelector: selector withObject: err];

        }
        if ([NSThread isMainThread]) {
            [invocation invoke];        
        }
        else{
            [invocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:YES];
        }
        [invocation getReturnValue:&result];
    }
    else
        NSLog(@"Missed Method");
    return result;
}

NSMethodSignature メソッドを使用すると、準備が整い、戻り値の型を要求できます。私はまだテストしていませんが、うまくいくはずです。

4

2 に答える 2

-1

リークまたは「不明なセレクターがインスタンスに送信される」問題を回避するために、これを作成してみてください。

SEL selector = NSSelectorFromString(@"methodName::");
if ([obj respondsToSelector:selector])
    [obj performSelector:selector withObject@[args,array]];
于 2013-06-03T14:33:03.613 に答える
-1

dispatch_syncブロックをすぐに実行する代わりに使用できますdispatch_async(ブロックが戻るまでコードはブロックされます)。

別の方法は、この回答で説明されているように、警告を一時的に抑制することです。

于 2013-06-03T14:45:53.320 に答える