0

UIBarButtonItem*buttonがあります。ユーザーがボタンを押すと、ウィンドウがポップアップするという考え方です。これは、ボタンのターゲット/アクションで宣言されます(つまり、ボタンをタップすると呼び出します

(void)showMyWindow:(id)sender

ここで、送信者はUIBarButtonItemです。

showMyWindow:メソッドでは、ポップアップウィンドウの描画には、送信者のフレームが必要です。現在、UIBarButtonItemは通常、そのフレームにアクセスすることを許可していません。ちょっとしたハックとして、送信者をUIViewにキャストしてから、このUIViewのフレームにアクセスしました。これがうまくいくとは思いませんでしたが、驚くべきことに、うまくいきました。

ただし、他の場所でshowMyWindow:メソッドも呼び出したいと思います。だから私はこのコード行を持っています:

[self performSelector:@selector(showMyWindow:) withObject:self.button];

ここで、私のアプリがクラッシュします。私はこれに問題を正確に特定しました:

(void)showMyWindow:(id)sender 
{
    //I should be checking before the cast here, but it helps illustrate the problem
    UIView *senderAsView = (UIView *)sender
    CGRect frame = senderAsView.frame;
    ...
}

重要なのは、target-actionを使用してメソッドを呼び出すと、このキャスト+フレームへのアクセスを実行できますが、performSelector:withObjectを使用する場合は実行できません。

なぜ違いがあるのですか?なぜこのキャストを実行できるのに、他のケースでは実行できないのですか?

ありがとう。

4

1 に答える 1

1

ちょっとしたハックとして、送信者を UIView にキャストしてから、この UIView のフレームにアクセスしました。これがうまくいくとは思っていませんでしたが、驚くべきことに、うまくいきます。

UIBarButtonItem は、UIView ではなく NSObject から派生したものであり、frame プロパティはありません。この場合の送信者は、おそらくバー ボタン アイテムではなく、それに属するプライベート ビュー (システム アイテムを使用している場合) またはそのカスタム ビュー プロパティのいずれかです。

「手動で」呼び出すと、実際にはフレームを持たない UIBarButtonItem インスタンスが送信され、UIView にキャストしてフレーム プロパティを要求するとクラッシュします。

senderデバッガーでオブジェクトを調べることで、実際に送信されているものを明確にすることができます。最初のインスタンスではビュー サブクラスになり、2 番目のインスタンスでは UIBarButtonItem (またはサブクラス) になります。

于 2012-07-25T09:06:10.877 に答える