views:

57

answers:

2

Ok here goes my situation:

I have a core-data generated class Quantity which has one of its attributes 'Value', marked as a float.

There's a convenience method in the Quantity class which helps me set this property:

- (void)setValueValue:(float)value_ {

    [self setValue:[NSNumber numberWithFloat:value_]];

}

Now when I set try set this value from a Controller like this,

Quantity *q = (Quantity *) [NSEntityDescription insertNewObjectForEntityForName:@"Quantity" inManagedObjectContext:self.managedObjectContext];

float qv = 100.0f;

[q setValueValue:qv];

the value gets set as 1.40129846e-43

I put breakpoints in both locations above, and while the tooltip correctly shows the value as 100.0 in the Controller class, it shows the incorrect value in the setter method.

And ultimately, the value that gets stored in the object and the db is the incorrect value.

Any clues as to what's happening here??

A: 

There is nothing wrong with the code you posted beyond the possibility of a naming collision. The dynamic accessor will have the name setValue: so setValueValue: runs the risk of confusing the runtime.

However, most likely, you are looking at a logging error i.e. the data is fine you are just displaying it incorrectly. If you use an NSLog with the wrong type in the format you will get very large, nonsensical outputs.

TechZen
+3  A: 

1.40129846e-43 is a very interesting number, and tells us what's happening here.

Specifically:

1.40129846e-43 = 100 * 2^-149

More simply, the value that you're observing is what you get if you interpret the integer value 100 as the encoding of a float.

What is most likely happening is that you haven't included the header that declares the setValueValue:(float) method, or that the declaration is otherwise not in scope at the location from which you are calling the method. This results in the compiler assuming that the method takes an integer argument instead of a floating-point argument.

Thus, the caller converts your 100.f value into the integer 100, which is then interpreted by the function as the encoding of the floating-point number you are observing.

The other possibility is that a similar type impedance mismatch is happening somewhere in your logging code.

TLDR: make sure you declare your functions before you use them in C-based languages.

Stephen Canon
+1 i never would've noticed that `1.40129846e-43 = 100 * 2^-149`. kudos, my friend. And in this case, I believe the compiler is actually converting it into an `id`, thus transforming it into a pointer.
Dave DeLong
@Dave: yes, the compiler is treating it as an `id`, but I didn't want to get too technical; pointers are "integer" values too, so the same actual conversions end up taking place either way.
Stephen Canon
You rock! It was precisely a case of missing header where the setValueValue method was declared. Including it solved the problem!
Sara
@Sara: happy to help.
Stephen Canon
And compile with -Werror!
tc.