Iphone 名为'的多个方法;标签';建立
为什么我在下面的代码中收到此警告:Iphone 名为'的多个方法;标签';建立,iphone,objective-c,ios,xcode,Iphone,Objective C,Ios,Xcode,为什么我在下面的代码中收到此警告: - (IBAction)shareThisActionSheet:(id)sender { int row = [sender tag]; //warning is here! Multiple methods named 'tag' found ... 问题是发送者被定义为(id)对象。在编译时,xcode不知道将传递给函数的对象类型 如果为特定对象类型编写此函数,则可以编写 - (IBAction)shareThisActionSheet
- (IBAction)shareThisActionSheet:(id)sender
{
int row = [sender tag]; //warning is here! Multiple methods named 'tag' found
...
问题是
发送者被定义为(id)
对象。在编译时,xcode不知道将传递给函数的对象类型
如果为特定对象类型编写此函数,则可以编写
- (IBAction)shareThisActionSheet:(UIButton*)sender
或者,您可以通过调用提示编译器对象的类型
int row = [(UIButton*)sender tag];
说明
问题是编译器在当前翻译单元中看到多个名为tag
的方法,并且这些声明具有不同的返回类型。一个可能是-[UIView tag]
,它返回一个NSInteger
。但它也看到了另一个标签的声明,也许:
@interface MONDate
- (NSString *)tag;
@end
然后编译器会发现一个歧义-是sender
aUIView
?或者是星期一
编译器警告您必须猜测发送方的类型。这实际上是在要求未定义的行为
分辨率
如果您知道参数的类型,请指定它:
- (IBAction)shareThisActionSheet:(id)sender
{
UIView * senderView = sender;
int row = [senderView tag];
...
否则,使用诸如isKindOfClass:
条件之类的条件来确定在发送消息之前声明变量的类型。正如其他答案所示,您也可以打字。巴斯蒂安是对的,您应该将发件人转换为如下按钮:
UIButton * button = (UIButton *)sender;
int row = button.tag;
如果你认为我是对的,为什么你要发布相同的答案而不是我的?因为我发布了一个不同的发送者类型(我认为它更正确,因为它更直观)使用long row=[senderView tag]代码>+1解释得很好。尽管有警告,但它在任何情况下都应该工作(使用id)。。对吗?@Ankit它不会起作用(参考:它要求的是未定义的行为)。如果所有可见的tag
方法都返回一个objc对象,这是可预测的。如果一个返回一个CGRect
,另一个返回一个objc对象,编译器可能会调用错误的objc\u msgSend
变量,您可能会破坏堆栈的一部分。如果编译器以另一种方式猜测错误,CGRect
可能会作为objc对象发送消息。你也可以切片内存,如果C++在那里,它甚至更复杂。(cont)(cont)另一种方法是查看生成的装配,针对生成的每个警告。更糟的是什么?如果未在TU中包含作为发送方传递的对象类型,则可能不会收到警告。此警告有效。谢谢你的解释。我只是将它转换为UIButton而不是UIView。运行时不应该知道id的实际类,所以要使用正确的标记方法吗?我的意思是,当ClassB派生自ClassA,并且两者都有一个名为tag
的方法时,当调用ClassA
和ClassB
的实例时,不应该调用相应的方法吗?或者问题出现在返回类型中?使用long row=[senderView tag]代码>