2009-12-21 69 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

相关问题