discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SMDoubleSlider usability on GNUstep


From: David Chisnall
Subject: Re: SMDoubleSlider usability on GNUstep
Date: Tue, 20 Feb 2018 14:55:04 +0000

On 20 Feb 2018, at 14:30, Yavor Doganov <yavor@gnu.org> wrote:
> 
> I think this condition is always false.  _cell.has_valid_object_value
> is NO and _object_value is nil.  So it jumps to NSCell.m:269 and
> SMDoubleSliderCell's -stringValue is called which calls -stringHiValue
> which in turn calls -doubleHiValue and from there the infinite
> recursion is in place.
> 
> At least this is what I observe in the debugger.

Ah, that makes sense - I’d missed that in the trace.  So now the question is 
what happens when you call -doubleValue on an NSCell in Cocoa when it has a 
string value?  Here’s a little test program that finds out:

#import <Cocoa/Cocoa.h>

@interface Proxy : NSProxy
{
        @public
        id obj;
}
@end

@implementation Proxy
- (BOOL)respondsToSelector: (SEL)aSelector
{
        return [obj respondsToSelector: aSelector];
}
- (NSMethodSignature*)methodSignatureForSelector: (SEL)aSelector
{
        return [obj methodSignatureForSelector: aSelector];
}
- (void)forwardInvocation: (NSInvocation*)anInvocation
{
        NSLog(@"%@ set to proxy", anInvocation);
        [anInvocation invokeWithTarget: obj];
}
@end

@interface Test : NSActionCell @end
@implementation Test
- (float)floatValue
{
        NSLog(@"-floatValue called\n");
        return [super floatValue];
}
- (NSString*)stringValue
{
        NSLog(@"-stringValue called\n");
        return [super stringValue];
}
@end

int main(void)
{
        @autoreleasepool
        {
                Test *t = [Test new];
                Proxy *p = [Proxy alloc];
                p->obj = @"0.23";
                [t setObjectValue: t];
                NSLog(@"Querying");
                NSLog(@"%f", [t floatValue]);
        }
}

The output is:

2018-02-20 14:46:39.917 a.out[85231:11731363] Querying
2018-02-20 14:46:39.917 a.out[85231:11731363] -floatValue called
2018-02-20 14:46:39.917 a.out[85231:11731363] 0.000000


So, from this we learn that Cocoa’s NSCell implementation doesn’t call any 
methods on either itself or the object to find the floating point value.  This 
is a bit odd, but at the very least we should fix GNUstep’s NSCell to query the 
object and not itself to find the string value.  The correct fix is probably:

- (float) floatValue
{
  if (_cell.has_valid_object_value == YES)
  {
    if ([_object_value respondsToSelector: @selector(floatValue)]))
    {
      return [_object_value floatValue];
    }
    if ([_object_value respondsToSelector: @selector(stringValue)]))
    {
      return [[_object_value stringValue] floatValue];
    }
  }
  return 0;
}

And apply similar fixes to the other *Value methods in NSCell.

You can hack around this brokenness by including the above method in a category 
on NSCell in your application (though please remember to remove it once GNUstep 
is fixed!).

David




reply via email to

[Prev in Thread] Current Thread [Next in Thread]