NSString containsString crashes

I am trying to filter an array according to one of its string fields.

Both nameLower and filterLower have an NSString value inside, and yet I keep getting:

__NSCFString containsString:]: unrecognized selector sent to instance 0x7f876b79e160 -(void) filterFriendsArray:(NSString*)filter { [_filteredFriendsArray removeAllObjects]; for (FacebookUser* user in _friendsArray) { NSString* nameLower = [user.user.name lowercaseString]; NSString* filterLower = [filter lowercaseString]; if ([nameLower containsString:filterLower]) [_filteredFriendsArray addObject:user]; } _displayedFriendsArray = _filteredFriendsArray; } 
+69
ios nsstring
Oct 16 '14 at 17:28
source share
6 answers

If you want your code to work on iOS 7 as well as iOS 8, you should use one of the rangeOfString calls instead. Basically, if the returned range is 0, the substring does not exist.

 /* These methods return length==0 if the target string is not found. So, to check for containment: ([str rangeOfString:@"target"].length > 0). Note that the length of the range returned by these methods might be different than the length of the target string, due composed characters and such. */ - (NSRange)rangeOfString:(NSString *)aString; - (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask; - (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)searchRange; - (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)searchRange locale:(NSLocale *)locale NS_AVAILABLE(10_5, 2_0); 

Obviously, this is trivial to implement containsString yourself in a category using rangeOfString:

 @implementation NSString (Contains) - (BOOL)myContainsString:(NSString*)other { NSRange range = [self rangeOfString:other]; return range.length != 0; } @end 
+118
Oct 17 '14 at 0:43
source share

compare range offring with NSNotFound

 NSRange range = [self rangeOfString:other]; if(range.location != NSNotFound){ //do something } 
+7
May 15 '15 at 11:06
source share

Use the following:

 if (![[NSString class] respondsToSelector:@selector(containsString)]) { //ios 7 NSRange range = [mystring rangeOfString:other]; if(range.location != NSNotFound){ //do something } } else //for iOS 8 { if ([mystring containsString: other]) { //do something } } 
+3
Mar 25 '16 at 20:26
source share

For those who encounter this in XLForm , make sure that when installing XLForm using containers

 platform :ios, '7' pod 'XLForm' 

It is already fixed in 3.1

from

 if ([cellClassString contains:@"/"]) { } 

to

 if ([cellClassString rangeOfString:@"/"].location != NSNotFound) { } 
0
May 2 '16 at 5:18
source share

I encapsulate my solution in YJKit, and you can call - [NSString containsString:] even for the old version, which is lower than iOS 8.

 bool _yj_streq(const char *str1, const char *str2, size_t length) { for (int i = 0; i < length; i++) { if (*str1++ != *str2++) { return false; } } return true; } - (BOOL)yj_containsString:(NSString *)string { NSAssert(string != nil, @"*** -[%@ containsString:] can not use nil argument.", [self class]); size_t len1 = (size_t)self.length; size_t len2 = (size_t)string.length; if (len1 == 0 || len2 == 0 || len1 < len2) { return NO; } const char *str1 = self.UTF8String; const char *str2 = string.UTF8String; for (size_t i = 0; i <= len1 - len2; i++) { const char *substr1 = str1 + i; if (_yj_streq(substr1, str2, len2)) { return YES; } else { continue; } } return NO; } 

Here is my source code: https://github.com/huang-kun/YJKit/blob/master/YJKit/Base/Foundation/Categories/Generics/NSString%2BYJCompatible.m

0
Aug 05 '16 at 9:39
source share

A quick version of the answer given by w0mbat:

 extension NSString { func compatibleContainsString(string: NSString) -> Bool{ let range = self.rangeOfString(string as String) return range.length != 0 } } 
-one
Jul 20 '15 at 11:17
source share



All Articles