views:

737

answers:

3

I'm getting the error on "float pos = [sender value];"...sender should be a UISlider that I set up in Interface Builder.

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;

THANKS.

+1  A: 

Since sender is of type 'id', the compiler doesn't know what it will return from its messages, and assumes they'll return an 'id' typed value. You need to either cast sender to UISlider (so the compiler knows that -value returns a float), or cast the returned value of the message to a float.

Asher Dunn
When I try to do this: "float pos = (float) [sender value];" it gives me error: "Pointer value used where floating point value was expected". What does this mean?
Devoted
You can't do it this way. The compiler assumes that [sender value] is an id, and you can't cast an id (an object pointer) to a float. You have to cast the sender to the right type so that the compiler knows what the return type of -value is.
Rob Napier
+3  A: 

While sender "should" be a UISlider, the compiler doesn't know that. All it sees is id, which it binds to the first matching method signature it can find; probably one that returns something other than a float (and as a final guess, the compiler will assume it returns an id).

You'll need to typecast this over to UISlider in this case:

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

Using NSAssert() or an if() to double-check that this is fact a UISlider wouldn't be a bad idea, but isn't strictly necessary.

Rob Napier
The cast to UISlider * should be before sender, but within the brackets. Now you cast the return value of [sender value] to a UISlider *
nash
thank you so much!!!
Devoted
+1  A: 

Since sender is of type id you should indicate what type it is.

Use the following:

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

Alternatively, you can use protocols. That way, you can receive different types of objects which, as long as they adhere to the protocol, can all be used in the same way.

@protocol myProtocol {
-(float)value;
}

-(void)myMethod:(id<myProtocol>)sender {
    float pos = [sender value];
}
nash
wait but what's the point of declaring as "id" then?
Devoted
with the latter syntax (cast to float) you can send any type of object, as long as it responds to the `value` message, and the result of the `value` method can be cast to a float. The type of object doesn't matter there. Alternatively, if you don't like casting, you can use protocols. `id<protocol> sender` in the declaration.
nash
You can't cast it to float at this point because the compiler still thinks that -value is returning an id at this point, and so won't be willing to cast to float. This would work for any object value return, but not for a float. Float return values are done differently in ObjC than object return values (it can't use objc_msgSend(), it has to use objc_msgSend_fpret()).
Rob Napier
True.. I'll change the answer to reflect the comment.
nash