3

What if I have a method that returns a CGFloat and that method could not find an expected number, I would like to return something like NSNotFound, but that is an NSInteger.

Whats the best practice for this ?

bobmoff
  • 2,415
  • 3
  • 25
  • 32
  • Maybe `CGFLOAT_MAX` or `CGFLOAT_MIN` will work for you. – rmaddy Dec 12 '14 at 15:24
  • 2
    A word of warning about `DBL_MIN`, `FLT_MIN` and `CGFLOAT_MIN`: Perhaps counterintuitively, they're *not* what you would conventionally think of as the "minimum" possible value, but rather they're "the smallest *positive* quantity that can be represented by that type". If you want the "most negative"/"minimum" value, use `-DBL_MIN`, `-FLT_MIN` or `-CGFLOAT_MIN`. – ipmcc Dec 12 '14 at 15:33

2 Answers2

3

You could use not a number (NaN).

See nan(), nanf() and isnan().

However for these issues, where there is no clearly defined non-value (it's worse with integers), then I prefer to use the following method semantics:

- (BOOL)parseString:(NSString *)string
            toFloat:(CGFloat *)value
{
    // parse string here
    if (parsed_string_ok) {
        if (value)
            *value = parsedValue;
        return YES;
    }
    return NO;
}
Droppy
  • 9,691
  • 1
  • 20
  • 27
  • 1
    Using `NaN` as a sentinel value has various pitfalls, for example if pass it into APIs that don't expect it, you can end up with bizarre unexpected results. CoreGraphics gets especially unhappy (crashes, etc) if you pass `NaN` values to it. To be safe, you end up having to check the result of every call that could ever return `NaN`, and at that point, you might as well just have done what @Droppy suggested and used an out-parameter and a `BOOL` return value. Every time I've used `NaN` as a sentinel value, I've ended up wishing I hadn't. – ipmcc Dec 12 '14 at 15:38
  • I think `Nan` ist just not "the iOS" way to go, so it's not expected and you should not use it. – iCaramba Dec 12 '14 at 15:49
  • I have acctually never created my own methods that takes an out parameter, but for this case it feel like a very good fit. thanks! – bobmoff Dec 13 '14 at 16:03
  • @bobmoff I would probably put `if (!value) return NO;` as the very first statement to save doing something which will never be used. – Droppy Dec 13 '14 at 18:05
3

A pretty clean way is to wrap it into an NSNumber:

- (NSNumber *)aFloatValueProbably
{
    CGFloat value = 0.0;
    if (... value could be found ...) {
        return @(value);
    }
    return nil;
}

Then you can check if the function returned nil for your non-existing value.

Accatyyc
  • 5,798
  • 4
  • 36
  • 51
  • I like this better than my answer. – Droppy Dec 12 '14 at 15:44
  • The drawback of this approach is obviously performance, since (most) NSNumbers are heap allocated. – ipmcc Dec 12 '14 at 15:52
  • this was what I was doing first, but returning an NSNumber doesnt feel right when the method is calculating the height of a cell which IS a CGFloat – bobmoff Dec 13 '14 at 16:01
  • Why do you need to calculate the height for "invalid" cells? I guess they shouldn't show up at all. – Accatyyc Dec 14 '14 at 08:20
  • I am getting the cached height for cells, and if the cell height isnt cached yet I want to the caller to know – bobmoff Dec 14 '14 at 21:33