3

私のiPhoneアプリには、ログインが必要なときにいつでもポップアップするログインビューコントローラーがあります。ユーザーがログインした後、私はこれを持っています:

    if ([self.presentingViewController respondsToSelector:@selector(userDidLogin)]) {
        [((id)self.presentingViewController) userDidLogin];
    } else {
        [self.presentingViewController dismissModalViewControllerAnimated:YES];            
    }

しかし、コンパイラーは「セレクターuserDidLoginの既知のインスタンスメソッドがありません」と文句を言い続けました。次に、ログインビューコントローラーにちなんで名付けられたインスタンスメソッドを追加しましたuserDidLoginが、もちろんそうではありませんでしたがself.presentingViewController、ビルドは成功しました。

この回避策は私には不合理に感じます。Xcodeのバグですか、それとも意図した動作ですか?後者ですか、その理由は何ですか?

4

1 に答える 1

4

userDidLoginコンパイラは、正しいコードを生成できるように、セレクターの戻り値の型を知る必要があります。

  • メッセージが構造体を返す場合、コンパイラは への呼び出しを生成する必要がある場合がありますobjc_msgSend_stret。(出典: Greg Parker のブログ.)
  • メッセージが浮動小数点数を返す場合、コンパイラは (一部のプラットフォームでは) への呼び出しを生成する必要がありますobjc_msgSend_fpret。(出典: Greg Parker のブログ.)
  • それ以外の場合、コンパイラは への呼び出しを生成する必要がありますobjc_msgSend

userDidLoginセレクターには引数がありませんが、セレクターに引数がある場合、コンパイラーは宣言された引数の型を認識して、引数を正しく渡すことができるようにする必要があります。

さらに、ARC を使用している場合、コンパイラは、必要に応じて戻り値のリリースを生成できるように、セレクターの戻り値の型と所有権の注釈を認識する必要があります。

これを処理する通常の方法は、メッセージ#importを宣言するクラスのヘッダー ファイルに対して行うだけです。セレクターがどこかuserDidLogin宣言されていることをコンパイラーが認識している限り、セレクターを.id

于 2012-09-15T06:35:30.583 に答える