我正在尝试了解用于iPhone开发的Objective-C,并且在查看有关操作的示例时,我经常看到以下内容:
- (IBAction)sliderMoved:(id)sender
{
UISlider *aSlider = (UISlider *)sender;
//rest of code goes here...
}
接受type(id)然后立即将其转换为(UISlider *)的目的是什么。为什么不具备以下内容:
- (IBAction)sliderMoved:(UISlider *)aSlider;
{
//rest of code goes here...
}
是否存在技术原因,或者仅仅是约定,还是为了便于阅读?
提前致谢,
答案 0 :(得分:6)
我认为这是一个惯例,因为UIControl并不总是以1:1的方式映射到IBAction。例如,您可以将UISwitch,UIButton和UITextField都映射到- (IBAction)syncUI:(id)sender;
方法。在这种情况下,无法指定类型。
我承认这只是我自己的心理理由,如果可以的话,肯定没有什么能阻止你在发送者类型中更明确。我通常是。
答案 1 :(得分:3)
事实上,如果您愿意,您可以将发件人指定为UIButton*
,如果您绝对确定该操作永远不会被任何其他类型的对象触发。如果操作取决于发件人是特定类型,那甚至可能是合适的。但是,通常情况下,发送方的类型对控制器无关紧要,将其指定为id
可让您灵活地更改视图而无需修改控制器。
您可能希望获得这种灵活性的一个原因是,即使您知道您将始终在应用中使用按钮来执行相关操作,也会让单元测试变得更加容易。
答案 2 :(得分:2)
IBActions
通常是通用的,可以由任何类触发,因此id
类型。如果您需要在方法中强制转换sender
变量,那么显然您关心的是sender
类,因此您应该更改方法签名以反映该方法。
答案 3 :(得分:0)
id
是抽象数据类型。如果您的方法可以从多个位置,另一个对象,按钮等调用,那么您可能并不总是知道发送方法调用的对象类型。我认为这主要是惯例,如果您要对发送者进行数据轮询,您必须知道它可以响应哪些方法(如果不是,您可以使用respondsToSelector询问:)。