SWIFT:如何使用Int值创建谓词?

Pat*_*iaW 20 core-data swift xcode6

我希望没有人告诉我RTFM,因为我在这里和Apple Developer上一直在努力解决这个问题并进行大量搜索.

我在此声明中收到EXC-BAD-ACCESS错误:

var thisPredicate = NSPredicate(format: "(sectionNumber == %@"), thisSection)
Run Code Online (Sandbox Code Playgroud)

thisSection的Int值为1,当我将鼠标悬停在其上时显示值1.但是在调试区域我看到了这个:

thisPredicate = (_ContiguousArrayStorage ...)
Run Code Online (Sandbox Code Playgroud)

使用String的另一个谓词显示为ObjectiveC.NSObject为什么会发生这种情况?

Mr *_*ley 30

You might try String Interpolation Swift Standard Library Reference. That would look something like this:

let thisSection = 1
let thisPredicate = NSPredicate(format: "sectionNumber == \(thisSection)")
Run Code Online (Sandbox Code Playgroud)

  • 创建谓词时请不要使用字符串插值。应选择由 Hugo Alonso 提供的这个答案:/sf/answers/2231960461/ 作为正确答案。 (5认同)

Hug*_*nso 24

You will need to change %@ for %i and remove the extra parenthesis:

Main problem here is that you are putting an Int where it's expecting an String.

Here's an example based on this post:

class Person: NSObject {
    let firstName: String
    let lastName: String
    let age: Int

    init(firstName: String, lastName: String, age: Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
    }

    override var description: String {
        return "\(firstName) \(lastName)"
    }
}

let alice = Person(firstName: "Alice", lastName: "Smith", age: 24)
let bob = Person(firstName: "Bob", lastName: "Jones", age: 27)
let charlie = Person(firstName: "Charlie", lastName: "Smith", age: 33)
let quentin = Person(firstName: "Quentin", lastName: "Alberts", age: 31)
let people = [alice, bob, charlie, quentin]


let thisSection = 33
let thisPredicate = NSPredicate(format: "age == %i", thisSection)

let _people = (people as NSArray).filteredArrayUsingPredicate(thisPredicate)
_people
Run Code Online (Sandbox Code Playgroud)

Another workaround would be to make thisSection's value an String, this can be achieved by String Interpolation or via description property of the Int.. lets say:

Changing:

let thisPredicate = NSPredicate(format: "age == %i", thisSection)
Run Code Online (Sandbox Code Playgroud)

for

let thisPredicate = NSPredicate(format: "age == %@", thisSection.description)
Run Code Online (Sandbox Code Playgroud)

or

let thisPredicate = NSPredicate(format: "age == %@", "\(thisSection)")
Run Code Online (Sandbox Code Playgroud)

of course, you can always bypass this step and go for something more hardcoded (but also correct) as:

let thisPredicate = NSPredicate(format: "sectionNumber == \(thisSection)")
Run Code Online (Sandbox Code Playgroud)

But take into account that for some weird reason String Interpolation (this kind of structure: "\(thisSection)") where leading to retain cycles as stated here

  • 花了两天时间找出为什么我的带有谓词的 fetchedresultcontroller 不起作用,解决方案是将 %@ 替换为 %i 。数据类型很重要,我们需要确保使用正确的类型进行过滤! (2认同)