Swift 4中NSPredicate搜索崩溃问题排查求助
解决Swift4中搜索字符串数组时的崩溃与RunLoop警告问题
首先我们先聚焦导致应用崩溃的核心问题,再顺带处理那个RunLoop警告。
崩溃原因分析
你遇到的NSInvalidArgumentException错误提示“Can't do a substring operation with something that isn't a string”,说明执行谓词过滤时,数组arrHomeTownData中存在非字符串类型的元素,或者Swift与Objective-C桥接过程中出现了类型不匹配的问题。
从Swift3升级到Swift4时,Swift原生类型与OC类型的桥接逻辑有细微调整,直接用NSArray的filtered(using:)方法处理Swift字符串数组,很容易触发这类类型兼容问题。
解决方案:改用Swift原生过滤逻辑
推荐直接使用Swift原生的数组过滤方法,完全避开NSPredicate与OC桥接的坑,代码更安全也更符合Swift的编码习惯:
// 先过滤掉数组中所有非字符串元素,从根源避免类型不匹配崩溃 let validHomeTownStrings = arrHomeTownData.compactMap { $0 as? String } // 用Swift原生方法实现忽略大小写的前缀匹配(对应原谓词的[cd]和BEGINSWITH逻辑) let filteredResults = validHomeTownStrings.filter { townName in townName.lowercased().hasPrefix(searchText.lowercased()) } // 如果你确实需要NSMutableArray类型,再进行转换 let arrSearchData = NSMutableArray(array: filteredResults)
这段代码的关键优化点:
- 用
compactMap筛除数组中非字符串的元素,彻底消除类型不匹配的隐患 - 用
lowercased()统一字符串大小写,实现原谓词[cd](忽略大小写、变音符号)的效果,hasPrefix对应BEGINSWITH的前缀匹配逻辑
关于RunLoop警告的处理
那个invalid mode 'kCFRunLoopCommonModes'的警告通常是系统内部或第三方库的线程调度问题,和你的搜索逻辑关联不大。如果警告持续出现,可以尝试确保搜索操作在主线程执行:
DispatchQueue.main.async { // 把上述搜索逻辑放在这里执行 }
一般来说,解决崩溃问题后这个警告可能会自动消失,即便存在也不会影响应用正常运行,可以暂时忽略。
内容的提问来源于stack exchange,提问作者Chirag Shah
相关产品推荐
相关产品推荐

