2009-12-21 60 views
0

我收到「float pos = [sender value];」的錯誤...「發件人應該是我在Interface Builder中設置的UISlider。錯誤:初始化中的類型不兼容? (iPhone,Objective-C)

ButtonViewController.m

- (IBAction)slide: (id)sender { 
float pos = [sender value]; 
loadValue.progress = pos; 
} 

ButtonViewController.h

@interface Button_Fun4ViewController : UIViewController { 
IBOutlet UIProgressView *loadValue; 
} 

- (IBAction)slide: (id)sender; 

感謝。

+0

答案很好,謝謝你,但是將它聲明爲「id」的意義是什麼呢? – Devoted 2009-12-21 05:30:19

+0

這裏是一個id的原因是所有的目標/動作方法都需要一個id並返回nil(IBAction是一個宏)。 addTarget:action:forEvents:在UIControl級別定義,因此必須適用於所有UIControls,而不僅僅是UISliders。它來自更長的目標/動作方法歷史,所有這些都通過了ID,所以即使投向UIControl也會讓有經驗的開發人員感到困惑。從技術上講,你可以輸入參數給UISlider,它可能會工作,但它可能會產生比解決更多的驚喜(因爲調用仍然不是類型安全的)。 – 2009-12-21 16:11:30

回答

3

雖然發件人「應該」是UISlider,但編譯器並不知道這一點。它看到的全部是id,它綁定到它可以找到的第一個匹配方法簽名;可能是返回浮點數以外的東西(作爲最終猜測,編譯器會假定它返回一個id)。

你需要在這種情況下,以這種強制轉換到UISlider:

- (IBAction)slide: (id)sender { 
    float pos = [(UISlider *)sender value]; 
    loadValue.progress = pos; 
} 

使用NSAssert()if()仔細檢查,這其實是一個UISlider不會是一個壞主意,但ISN絕對必要。

+0

轉換爲UISlider *應在發件人之前,但在括號內。現在您將[sender value]的返回值轉換爲UISlider * – nash 2009-12-21 05:26:37

1

由於發件人的類型爲'id',因此編譯器不知道它將從其消息中返回什麼內容,並假定他們將返回'id'類型的值。您需要將發件人轉換爲UISlider(因此編譯器知道-value返回一個浮點數),或者將返回的消息值轉換爲浮點數。

+0

當我嘗試這樣做:「float pos =(float)[sender value];」它給我錯誤:「在預期浮點值時使用的指針值」。這是什麼意思? – Devoted 2009-12-21 05:26:52

+0

你不能這樣做。編譯器假定[sender value]是一個id,並且你不能將一個id(一個對象指針)轉換爲一個float。您必須將發件人轉換爲正確的類型,以便編譯器知道返回類型的值是什麼。 – 2009-12-21 05:42:55

1

由於sender的類型是id您應該指出它是什麼類型。

使用以下命令:

float pos = [(UISlider *)sender value]; 

或者,你可以使用的協議。這樣,您可以接收不同類型的對象,只要它們遵守協議,都可以以相同的方式使用。

@protocol myProtocol { 
-(float)value; 
} 

-(void)myMethod:(id<myProtocol>)sender { 
    float pos = [sender value]; 
} 
+0

等待,但是那麼聲明爲「id」又有什麼意義呢? – Devoted 2009-12-21 05:29:40

+0

使用後一種語法(轉換爲浮點數),只要響應'value'消息,就可以發送任何類型的對象,並且'value'方法的結果可以轉換爲浮點數。對象的類型在那裏並不重要。或者,如果您不喜歡投射,則可以使用協議。聲明中的'id sender'。 – nash 2009-12-21 05:39:07

+1

此時你不能將它強制轉換爲浮點,因爲編譯器仍然認爲-value此時正在返回一個id,所以不會願意轉換爲float。這將適用於任何對象值返回,但不適用於浮點數。在ObjC中,浮點返回值與對象返回值不同(它不能使用objc_msgSend(),它必須使用objc_msgSend_fpret())。 – 2009-12-21 05:51:46

相關問題