NSString containsString崩溃


70

我正在尝试根据其字符串字段之一过滤数组。

nameLower和filterLower都在内部具有NSString值,但是我不断得到:

__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;
}

46
您是否在低于8的iOS上运行?该containsString:方法只加入在IOS 8.
伊恩麦克唐纳

6
很好奇的containsString:是没有在线记录。
Hot Licks 2014年

@IanMacDonald你是对的..发布它作为答案,所以我可以接受..
Asaf Nevo 2014年

@HotLicks一直都没有记录。
user3344977 2015年

Answers:


119

如果要让代码在iOS 7和iOS 8上运行,则应改用rangeOfString调用之一。基本上,如果返回的范围的长度为零,则子字符串不存在。

/* 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);

显然,使用rangeOfString自己在类别中实现containsString很简单:

@implementation NSString (Contains)

- (BOOL)myContainsString:(NSString*)other {
  NSRange range = [self rangeOfString:other];
  return range.length != 0;
}

@end

在osx上,rangeOfString似乎返回nil而不是0(如果不包含字符串)
Morten J

2
//“在osx上,如果不包含字符串,则rangeOfString似乎返回nil而不是0”我上次检查时,nil等于零。
w0mbat

5
真高兴在编译时看到此问题
user230910 2015年

2
根据Apple的文档,应将结果与NSNotFound而不是 0或进行比较nil
ChristofferÅrstrand'15

4
是的,检查NSNotFound的范围位置return range.location != NSNotFound;
johnpatrickmorgan


3

使用以下内容:

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
          }                             
     }

0

对于那些在XLForm中遇到此问题的,请确保在安装时XLForm使用pod

platform :ios, '7'
pod 'XLForm'

它已经固定在 3.1

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

}

if ([cellClassString rangeOfString:@"/"].location != NSNotFound) {

}

0

我将解决方案封装在YJKit中,即使对于iOS 8以下的旧版本,您也可以调用-[NSString containsString:]。

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;
}

这是我的源代码:https : //github.com/huang-kun/YJKit/blob/master/YJKit/Base/Foundation/Categories/Generics/NSString%2BYJCompatible.m


1
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。
Roman Marusyk '16

-1

w0mbat给出的答案的Swift版本:

extension NSString {
    func compatibleContainsString(string: NSString) -> Bool{
        let range = self.rangeOfString(string as String)
        return range.length != 0
    }
}

范围没有成员长度。
lostintranslation

编辑我的答案,显然字符串的范围不包含“长度”,但NSString包含。
克里斯C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.