模拟器和设备之间的不同NSPredicate行为

Mic*_*ael 2 nspredicate swift

我知道我在这里做'错误'的事情,但它适用于所有情况,除了在模拟器中定位iPad Air或Retina时 - 它适用于不同设备的模拟器或支持的物理设备(6S和Retina测试) ,但在模拟器中运行时在iPad Air或Retina上失败.

最新版本的Realm(0.97)和iOS(9.2)以及XCode(7.2).为了重现这个问题,这是一个非常人为的例子......

import UIKit
import RealmSwift

class MyObject: Object {
    dynamic var x: Int64 = 0
    dynamic var y: Int64 = 0
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        print("Realm path: \(Realm.Configuration.defaultConfiguration.path!)")

        let realm = try! Realm()

        try! realm.write({
            realm.deleteAll()
        })

        let myObject = MyObject()
        myObject.x = 1
        myObject.y = 2

        try! realm.write({
            realm.add(myObject)
        })

        let findX: Int64 = 1
        let findY: Int64 = 2

        let p1 = NSPredicate(format: "x == %d and y == %d", findX, findY)
        let p2 = NSPredicate(format: "x == %d", findX)
        let p3 = NSPredicate(format: "x == %lld and y == %lld", findX, findY)

        print("Test 1: Fail on iPad retina in Simulator: \(realm.objects(MyObject).filter(p1).count)")
        print("Test 2: Pass on all platforms: \(realm.objects(MyObject).filter(p2).count)")
        print("Test 3: Pass on all platforms: \(realm.objects(MyObject).filter(p3).count)")

        return true
    }

}
Run Code Online (Sandbox Code Playgroud)

当你运行它时,所有这些测试"应该"打印"1"(是的,测试3是最正确的).但是,至少对我来说,如果在模拟器中运行并针对iPad Air或Retina,则第一个测试返回"0".他们在物理设备上工作.

我知道第三个测试是如何编码的,但是(1)为什么第二个测试工作呢?(2)为什么这只发生在这些特定设备的模拟器中?(而且我知道你花了很长时间才找出根本原因!)

bda*_*ash 7

您的问题是用于构造的格式字符串NSPredicate.您可以通过将代码简化为以下内容来查看:

let findX: Int64 = 1
let findY: Int64 = 2

let p1 = NSPredicate(format: "x == %d and y == %d", findX, findY)
let p2 = NSPredicate(format: "x == %lld and y == %lld", findX, findY)

print(p1)
print(p2)
Run Code Online (Sandbox Code Playgroud)

在32位模拟器中打印:

x == 1 AND y == 0
x == 1 AND y == 2
Run Code Online (Sandbox Code Playgroud)

在64位模拟器中,它打印:

x == 1 AND y == 2
x == 1 AND y == 2
Run Code Online (Sandbox Code Playgroud)

这表明使用格式字符串会x == %d and y == %d导致谓词不表达您想要的查询.发生这种情况的原因是格式说明符p1与您传递的参数的类型不匹配.特别是,%d格式字符串希望你传递一个,Int但你传递了一个Int64.通过%lld正确使用它可以查找要传递的64位值.