[Top][All Lists]

[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 <address@hidden> 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
        id obj;

@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];

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

int main(void)
                Test *t = [Test new];
                Proxy *p = [Proxy alloc];
                p->obj = @"0.23";
                [t setObjectValue: t];
                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!).


reply via email to

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