0

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'
arc4randall
  • 3,275
  • 3
  • 27
  • 40
  • 1
    Several problems: 1) You can't directly store an `NSRange` in a dictionary (or other collection). 2) `NSRange` is a `struct`, not a class. Don't use it with pointers. 3) Don't use `CFBridgingRetain` with a `struct`. Wrap the `NSRange` in an `NSValue` to use it with collections. – rmaddy Jun 18 '14 at 00:20
  • @maddy, you should flesh out your comment a little and submit it as an answer. You've touched on most of the things that are wrong with the OP's code, so you deserve the "accepted answer" rep points. – Duncan C Jun 18 '14 at 00:33
  • I agree 100%. Thanks rmaddy. I'll gladly check the box if you submit this as an answer :) – arc4randall Jun 18 '14 at 00:39

1 Answers1

3

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];
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579