FROM : Ken Thomases
DATE : Mon Mar 24 21:02:15 2008
On Mar 23, 2008, at 8:18 PM, Tron Thomas wrote:
> I am having a problem with Cocoa bindings that I cannot figure out.
> There is some object that is observing the value of another
> object. An example for the relevant implementation of the classes
> is as follows:
>
> @implementation SomeObject
> - (id)initWithObject:
> (AnotherObject*)object
> {
> self = [super init];
> if(nil == self){
> return nil;
> }
> [object addObserver:self forKeyPath:@"value" options:0
> context:nil];
>
> return self;
> }
>
> - (void)observeValueForKeyPath:(NSString*)keyPath
> ofObject:(id)object
> change:(NSDictionary*)change
> context:(void*)context
> {
> if([keyPath isEqualToString:@"value"]){
> float value = 2.0f;
> value = [object value];
At this point, the compiler only knows that object is an id. It
doesn't know the specific class. So, of any of the "value" methods
it might know about, it doesn't know which specific one is meant.
Normally that wouldn't matter, but when you're dealing with float
returns (or struct returns) the generated code would be different.
In other words, the compiler is generating the code here as though it
were invoking a "value" method that returns an int. What is actually
being invoked is a method which returns a float. The mismatch causes
the problem.
> ::NSLog(@"The observed value for %@ is %f", object, value);
> }
> }
> @end
>
> @implementation AnotherObject
> - (void)setValue:
> (float)value
> {
> _value = value;
> ::NSLog(@"The value for %@ was updated to %f.", self, _value);
> }
>
> - (float)value
> {
> ::NSLog(@"The value for %@ is %f.", self, _value);
> return _value;
> }
> @end
>
> _value is a private member of the AnotherObject class.
>
> When I run the program, I get output like the following:
>
> 2008-03-23 17:48:24.218 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 2.000000.
> 2008-03-23 17:48:24.219 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.223 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.224 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.225 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.267 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 3.000000.
> 2008-03-23 17:48:24.268 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.270 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.270 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.273 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.315 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 4.000000.
> 2008-03-23 17:48:24.319 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
> 2008-03-23 17:48:24.320 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.321 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
> 2008-03-23 17:48:24.322 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
>
>
> The problem is even though the value is updated to some non-zero
> value, the observed value is always zero. I have tried stepping
> through the code and verified that when I step into [AnotherObject
> value] method from the call in [SomeObject
> observeValueForKeyPath:ofObject:change:context:], the _value
> instance member is non-zero. Yet when I return to the calling
> method, the local value variable gets set to zero. This does not
> make sense.
>
> What would allow the SomeObject instance to get the proper value
> for AnotherObject when observing it?
There are two approaches to fixing this:
1) Use a method name which won't be ambiguous about its return type,
such as floatValue. It's not the name that actually matters, it's
that all of the "floatValue" methods that the compiler might know
about at that point have a return type of float -- because what
perverse soul would create a floatValue method that returned
something other than float -- so there's no chance of confusion.
2) Cast "object" to the specific class that you know it to be (i.e.
AnotherObject*). You would have to make sure you've imported
AnotherObject.h, of course.
Cheers,
Ken
DATE : Mon Mar 24 21:02:15 2008
On Mar 23, 2008, at 8:18 PM, Tron Thomas wrote:
> I am having a problem with Cocoa bindings that I cannot figure out.
> There is some object that is observing the value of another
> object. An example for the relevant implementation of the classes
> is as follows:
>
> @implementation SomeObject
> - (id)initWithObject:
> (AnotherObject*)object
> {
> self = [super init];
> if(nil == self){
> return nil;
> }
> [object addObserver:self forKeyPath:@"value" options:0
> context:nil];
>
> return self;
> }
>
> - (void)observeValueForKeyPath:(NSString*)keyPath
> ofObject:(id)object
> change:(NSDictionary*)change
> context:(void*)context
> {
> if([keyPath isEqualToString:@"value"]){
> float value = 2.0f;
> value = [object value];
At this point, the compiler only knows that object is an id. It
doesn't know the specific class. So, of any of the "value" methods
it might know about, it doesn't know which specific one is meant.
Normally that wouldn't matter, but when you're dealing with float
returns (or struct returns) the generated code would be different.
In other words, the compiler is generating the code here as though it
were invoking a "value" method that returns an int. What is actually
being invoked is a method which returns a float. The mismatch causes
the problem.
> ::NSLog(@"The observed value for %@ is %f", object, value);
> }
> }
> @end
>
> @implementation AnotherObject
> - (void)setValue:
> (float)value
> {
> _value = value;
> ::NSLog(@"The value for %@ was updated to %f.", self, _value);
> }
>
> - (float)value
> {
> ::NSLog(@"The value for %@ is %f.", self, _value);
> return _value;
> }
> @end
>
> _value is a private member of the AnotherObject class.
>
> When I run the program, I get output like the following:
>
> 2008-03-23 17:48:24.218 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 2.000000.
> 2008-03-23 17:48:24.219 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.223 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.224 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.225 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 2.000000.
> 2008-03-23 17:48:24.267 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 3.000000.
> 2008-03-23 17:48:24.268 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.270 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.270 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.273 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 3.000000.
> 2008-03-23 17:48:24.315 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> was updated to 4.000000.
> 2008-03-23 17:48:24.319 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
> 2008-03-23 17:48:24.320 MyProgram[276:813] The observed value for
> <AnotherObject: 0x188240> is 0.000000
> 2008-03-23 17:48:24.321 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
> 2008-03-23 17:48:24.322 MyProgram[276:813] The value for
> <AnotherObject: 0x188240> is 4.000000.
>
>
> The problem is even though the value is updated to some non-zero
> value, the observed value is always zero. I have tried stepping
> through the code and verified that when I step into [AnotherObject
> value] method from the call in [SomeObject
> observeValueForKeyPath:ofObject:change:context:], the _value
> instance member is non-zero. Yet when I return to the calling
> method, the local value variable gets set to zero. This does not
> make sense.
>
> What would allow the SomeObject instance to get the proper value
> for AnotherObject when observing it?
There are two approaches to fixing this:
1) Use a method name which won't be ambiguous about its return type,
such as floatValue. It's not the name that actually matters, it's
that all of the "floatValue" methods that the compiler might know
about at that point have a return type of float -- because what
perverse soul would create a floatValue method that returned
something other than float -- so there's no chance of confusion.
2) Cast "object" to the specific class that you know it to be (i.e.
AnotherObject*). You would have to make sure you've imported
AnotherObject.h, of course.
Cheers,
Ken
| Related mails | Author | Date |
|---|---|---|
| Tron Thomas | Mar 24, 02:18 | |
| Ken Thomases | Mar 24, 21:02 | |
| Tron Thomas | Mar 25, 04:48 |






Cocoa mail archive

