Search code examples
iosobjective-cnsrangensexceptionnsrangeexception

NSRange changes itself inside for loop


I have an NSDictionary of NSRange objects, with keys for their index in the array. I am attempting to use each of these ranges to create substrings of a larger string, and place each of these substrings in the array. I basically have this completed, but the NSRange is mysteriously changing it's value in the code, causing it to crash and throw an exception. Here is my code:

NSMutableArray*subStringArray = [[NSMutableArray alloc] init];
for(id key in aDict){
            NSRange* range = CFBridgingRetain([aDict objectForKey:key]);
            NSLog(@"This is a single range: %@",range);
            //Range is changed here somehow
            NSString* aSubString = [self.content substringWithRange:*range];
            NSLog(@"%@",aSubString);
            [subStringArray addObject:aSubString];
        }

My Log output looks like this:

This is a single range: NSRange: {1874, 72}
2014-06-17 20:07:30.100 testApp[8027:60b] *** Terminating app due to uncaught exception     
'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range {4318599072, 4} out of bounds; string length 5562'

Solution

  • By popular demand :)

    The main issue with your code is that you are directly storing an NSRange struct in your dictionary. You can't do this. You must wrap the NSRange in an NSValue to store it in the dictionary.

    To add the NSRange you can do:

    NSRange range = ... // some range
    NSValue *value = [NSValue valueWithRange:range];
    dict[someKey] = value;
    

    Then your posted code becomes:

    for (id key in aDict) {
        NSValue *value = aDict[key];
        NSRange range = [value rangeValue];
        NSLog(@"This is a single range: %@",range);
        //Range is changed here somehow
        NSString* aSubString = [self.content substringWithRange:range];
        NSLog(@"%@",aSubString);
        [subStringArray addObject:aSubString];
    }