ios NSString containsString 崩溃

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26410420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:14:15  来源:igfitidea点击:

NSString containsString crashes

iosnsstring

提问by Asaf Nevo

I'm trying to filter an array according to one of it's string fields.

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

Both nameLower and filterLower has NSString value inside, and yet i keep getting:

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

回答by w0mbat

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 range returned has a length of zero, the substring is not there.

如果您希望您的代码在 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);

Obviously it's trivial to implement containsString yourself in a category using rangeOfString:

显然,使用 rangeOfString 在类别中自己实现 containsString 是微不足道的:

@implementation NSString (Contains)

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

@end

回答by Deepak Badiger

compare rangeOfString with NSNotFound

比较 rangeOfString 和 NSNotFound

NSRange range = [self rangeOfString:other];
if(range.location != NSNotFound){
    //do something
}

回答by Ram G.

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

回答by Ted

For those who encountered this in XLForm, make sure when you install XLFormusing pods

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

platform :ios, '7'
pod 'XLForm'

It is already fixed in 3.1

它已经固定在 3.1

from

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

}

to

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

}

回答by huang-kun

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

我将我的解决方案封装在 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;
}

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

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

回答by Chris C

Swift version of the answer given by w0mbat:

w0mbat给出的答案的Swift版本:

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