UIBarButtonItem:对于目标操作调用与performSelector:withObject的处理方式不同:

时间:2012-07-25 08:44:58

标签: ios uibarbuttonitem performselector

我有一个UIBarButtonItem *按钮。想法是用户按下按钮然后弹出一个窗口。这是在按钮的目标/动作中声明的(即点击按钮调用

(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:

为什么会有区别?为什么这个演员表可以在一个案例中执行而不能在另一个案例中执行?

感谢。

1 个答案:

答案 0 :(得分:1)

  

作为一个黑客攻击,我已经将发送者强制转换为UIView,然后访问了这个UIView的框架。我不认为这会起作用,但令人惊讶的是,确实如此。

UIBarButtonItem来自NSObject,而不是UIView,并且没有frame属性。在这种情况下,发件人很可能不是您的栏按钮项,而是属于它的私人视图(如果您使用的是系统项)或其自定义视图属性。

当你“手动”调用它时,你真的 发送没有框架的UIBarButtonItem实例,当你将它转换为UIView并且询问它的frame属性时会崩溃。

您可以通过检查调试器中的sender对象来澄清实际发送的内容。它将是第一个实例中的视图子类,第二个实例中是UIBarButtonItem(或子类)。