在装有iOS 10.3的iPhone 5和iPad 4上非常烦人的NSPredicate崩溃

问题描述 投票:0回答:2

正如这个问题的标题所言,NSPredicate初始化时我的代码崩溃了。到目前为止,我发现崩溃仅发生在具有iOS 10.3的iPhone 5和iPad 4第四代上。在具有相同iOS 10.3的其他设备上,一切正常。

func getPredicate(for serviceId: Int64, startingFrom step: Int) -> NSPredicate {
    let predicate = NSPredicate(format: "serverID == %i AND step == %i AND type == %@", 
                                serviceId, step, "button")
    return predicate
}

blog post完美地描述了我的问题,在32位CPU设备上我也遇到了同样的崩溃问题。尽管文章中给出的解决方案帮助我避免了崩溃,但是当我在获取请求中使用CoreData时,总是返回nil结果。

是否有解决此问题的解决方法?

开发工具:

  • XCode版本:11.2.1
  • Swift语言版本:Swift 5
  • 设备:iPhone 5和iPad第四代
ios swift nspredicate
2个回答
1
投票

%i格式用于格式化C int类型的值,在所有当前的iOS平台上,该值为32位整数。相反,传递64位整数(在您的情况下为serviceId)是未定义的行为,可能会导致崩溃。

64位整数的正确格式为%lli(对于long long int),而Int的正确格式(可以为32位或64位)为%li(对于[ C0])。

因此,这在32位和64位设备上均有效:

long int

更简便的方法是将所有数字都转换为let predicate = NSPredicate(format: "serverID == %lli AND step == %li AND type == %@", serviceId, step, "button") ,因为您不必记住各种整数类型的正确格式。 NSNumber是“对象”(Objective-C类的实例),可以简单地用NSNumber格式进行格式化:

%@

作为let predicate = NSPredicate(format: "serverID == %@ AND step == %@ AND type == %@", serviceId as NSNumber, step as NSNumber, "button") 传递参数may偶然,但是格式错误,仍然是不确定的行为。


1
投票

我不知道是什么原因,但是当我用另一个初始化器创建了argumentArray时,崩溃停止了,NSPredicate在具有任何CoreData版本的所有设备上给出令人满意的结果。NSPredicate的另一个将参数作为array的初始化程序解决了我的问题。

iOS
© www.soinside.com 2019 - 2024. All rights reserved.