Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for substring of NSString crashing

I've tried checking for an occurrence of a substring in an NSString in two ways, both have crashed. This is an NSString object I get from one of my NSManagedObject's properties.

  1. Using NSRange

    NSString *searchString = @"drive";

    NSRange range = [text rangeOfString:searchString options:(NSCaseInsensitiveSearch)];

    if (range.location != NSNotFound) { NSLog(@"Found"); }

  2. Using NSScanner

    NSScanner *scanner = [NSScanner scannerWithString:text];

    NSLog(@"%d",[scanner scanString:searchString intoString:nil]);

Both of these work when text = @"drive" but cause EXC_BAD_ACCESS crashes when the text is "i drive", or "drive to". Nothing happens if the text is "idrive" or "driveto".

Even stranger, sometimes the examples throw NSInvalidArgumentExceptions, saying that I tried to pass an NSCFSet or a DateComponents object to rangeOfString:, neither of which I use in my app.

Any ideas?

like image 335
nathan Avatar asked Sep 05 '11 15:09

nathan


2 Answers

If you sometimes get EXC_BAD_ACCESS and sometimes get the message "object-of-type-you-weren't expecting does not respond to method" the chances are you are not retaining the object for long enough and it is getting deallocated before you get to where you use it.

If the memory hasn't been reused when you get there, things will appear to work. If the space has been reused for another object and aligns perfectly i.e. same pointer, you'll get something like "x does not respond to selector". If it's overwritten in such a way that the pointer does not point to a valid object, you'll get EXC_BAD_ACCESS

like image 85
JeremyP Avatar answered Nov 05 '22 07:11

JeremyP


The following worked perfectly for me including the spaces.

NSString *string = @"hello one two three";
if ([string rangeOfString:@"one two"].location == NSNotFound) {
    NSLog(@"string does not contain substring");
} else {
    NSLog(@"string contains substring!");
}

And if you want it to be case insensitive, just convert both the string and the search string to lowercase. You should be knowing how to do that I guess.

like image 37
Bourne Avatar answered Nov 05 '22 06:11

Bourne