NSRange: range.location != NSNotFound vs. range.length > 0

20,728

Solution 1

The two checks are not always identical. It depends on how the range was generated. Example:

NSRegularExpression *re = [NSRegularExpression
    regularExpressionWithPattern:@"(?= )" options:0 error:NULL];
NSTextCheckingResult *result = [re firstMatchInString:@"hello world"
    options:0 range:NSMakeRange(0, 11)];
NSLog(@"range = %@", NSStringFromRange(result.range));

The range's length is 0, but its location is 5, not NSNotFound.

Solution 2

The answer depends on the function/method you are using. NSRange is just a struct so you need to read the documentation for the function/method you are calling.

Examples:

NSRangeFromString
Returns a range from a textual representation.

... If aString does not contain any integers, this function returns an NSRange struct whose location and length values are both 0.

In this case checking for NSNotFound would not work.


-[NSString rangeOfString:]

... Returns {NSNotFound, 0} if aString is not found or is empty (@"").

Here it is documented that location will be NSNotFound and the length will be 0 so either of the checks would work, however, I would recommend checking the location against NSNotFound.

Share:
20,728
MikeS
Author by

MikeS

#SOreadytohelp

Updated on January 01, 2020

Comments

  • MikeS
    MikeS over 4 years

    I'm going through some older code in one of my apps and fixing up the code in areas that could be potentially problematic.

    I'm seeing a lot of old code using...

    NSRange range = //determine range here....
    if(range.length > 0)
    {
        //do stuff
    }
    

    Is that code "fine", or should I change it to this?

    NSRange range = //determine range here....
    if(range.location != NSNotFound)
    {
        //do stuff
    }
    

    Are these two methods identical, essentially, or not?

  • MikeS
    MikeS over 11 years
    So in implementation, they are identical, but the preferred usage is checking if range.location equals NSNotFound or not?
  • rooster117
    rooster117 over 11 years
    I feel we are now just talking about style since I believe both will give you the same result. I would just think that if you read the second one it flows and makes sense "the location of the range is found or not found" as opposed to the first which requires interpretation. Either way its pretty minor and you may just pick one convention for the entire file for consistency sake.
  • MikeS
    MikeS over 11 years
    Interesting counter example to the theory that checking for location equalling NSNotFound and length > 0 are essentially the same...
  • MikeS
    MikeS over 11 years
    So it sounds like what really matters in my question is how the range is determined and what I'm trying to do with the range.
  • Joe
    Joe over 11 years
    Yes, read the documentation to determine what you need to check for.
  • Joe
    Joe over 11 years
    For a reference here what the documentation has to say for NSRegularExpressions: If the result returned is non-nil, then [result range] will always be a valid range, so it is not necessary to compare it against {NSNotFound, 0}. However, for some regular expressions (though not the example pattern) some capture groups may or may not participate in a given match. If a given capture group does not participate in a given match, then [result rangeAtIndex:idx] will return {NSNotFound, 0}.