2012-01-11 59 views
5

爲什麼我得到這樣的警告在下面我的代碼:命名爲「標記」多種方法找到

- (IBAction)shareThisActionSheet:(id)sender 
{ 
    int row = [sender tag]; //warning is here! Multiple methods named 'tag' found 
    ... 

回答

12

說明

問題是,編譯器在第th處看到多個名爲tag的方法當前翻譯單元,這些聲明具有不同的返回類型。其中一個可能是-[UIView tag],它返回NSInteger。但它也看到了tag再次聲明,或許是:

@interface MONDate 
- (NSString *)tag; 
@end 

那麼編譯器看到的歧義 - 是sender一個UIView?或者它是MONDate

編譯器的警告你,它必須猜測什麼sender的類型是。這確實是要求未定義的行爲。

分辨率

如果你知道參數的類型,然後將其指定:

一樣,使用的東西,如isKindOfClass:條件來確定類型變量聲明爲短信之前。正如其他答案顯示的那樣,你也可以進行類型轉換。

+1

+1很好的解釋。但它應該在任何情況下工作(使用ID),儘管警告..對吧? – 2012-01-11 11:24:27

+0

@Ankit它*不會*工作(參考:它要求未定義的行爲)。如果所有可見的'tag'方法都返回一個objc對象,那麼這是可預測的。如果你返回一個'CGRect'而另一個返回一個objc對象,那麼編譯器可能最終會調用錯誤的'objc_msgSend'變體,你可能會破壞你的堆棧的一部分。如果編譯器猜測其他方式並且錯誤,則可以將CGRect作爲objc對象進行消息傳遞。你也可以分割內存,如果C++在那裏,它就更加複雜了。 (續) – justin 2012-01-11 11:36:34

+0

(續)替代方法是查看生成的程序集,生成每個警告。更糟糕的是?如果您未包含在TU中作爲'sender'傳遞的對象的類型,則可能不會收到警告。 – justin 2012-01-11 11:39:20

3

的問題是,sender被定義爲(id)對象。在編譯時xcode不知道什麼樣的對象會傳遞給你的函數。

如果你寫的這個功能對特定的對象類型,你可以,你可以寫例如

- (IBAction)shareThisActionSheet:(UIButton*)sender 

,或者你可以提示編譯器對象的類型與呼叫

int row = [(UIButton*)sender tag]; 
2

巴斯蒂安是正確的,你應該將發送者轉換爲按鈕這樣的:

UIButton * button = (UIButton *)sender; 
int row = button.tag; 
+3

如果你認爲我是對的,你爲什麼發佈相同的答案,而不是upvoting我? – Bastian 2012-01-11 11:07:17

+1

因爲我發佈了一些不同的發件人(我認爲它更正確,因爲它更直觀) – Stas 2012-01-11 11:56:36

相關問題