NSExpression子查询用法

时间:2016-10-17 16:45:46

标签: ios swift

Swift 3引入了新的NSExpresion类型Subquery expression。我试图在Playground中使用它,但无法让它工作。

首先,我在MyPlayground的Sources文件夹中创建了一个类:

$source = Import-Csv -Path C:\tmp\ib20161016.csv -Delimiter ","

在MyPlayground中,集合表达式创建为e1(我尝试了聚合和格式表达式,所有都是集合表达式但在后期失败):

// example classes
public class Person {
  public let name: String
  public let birthYear: Int

  init(name pName: String, birthYear year : Int) {
    name = pName
    birthYear = year
  }
}

public class Parent: Person {
  public var children: [Person] = [Person]()
  override init(name pName: String, birthYear year : Int) {
    super.init(name: pName, birthYear: year)
  }
}

public class TestSubquery {
  // Method to get a Parent
  public class func getParent() -> Parent {
    let p = Parent(name: "Bob", birthYear: 1997)
    let c = Person(name: "Tonny", birthYear: 2010)
    p.children.append(c)
    return p
  }
}

然后创建一个子查询表达式为e2:

let p = TestSubquery.getParent()
print("\(p.children.count)") // 1
let e1 = NSExpression(forAggregate: p.children)
// let e1 = NSExpressoin(format: "%@", p.children)
print("e1: \(e1)")
//e1: {MyPlayground_Sources.Person}

最后,当我尝试从表达式获取结果时,发生错误:

let e2 = NSExpression(forSubquery: e1, usingIteratorVariable: "x", predicate: "$x.birthYear > 0")
print("\(e2)")
// SUBQUERY({MyPlayground_Sources.Person}, $x, $x.birthYear > 0)

错误消息如下:

*** NSForwarding: warning: object 0x6080000547f0 of class 'MyPlayground_Sources.Person' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[MyPlayground_Sources.Person expressionValueWithObject:context:]

看起来无法找到键值。我不确定构建子查询表达式有什么问题。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

经过几天的挣扎,我想我得到了一个解决方案!

首先,集合中的类(例如数组中的Person)必须从NSObject继承。

public class Person : NSObject {

其次,根据Apple的Developer documentation

enter image description here

也就是说,第三个参数应为NSPredicate类型(即使String属于Any?)。更新后的e2应该是:

let predicate = NSPredicate(format: "$x.birthYear > 0")
let e2 = NSExpression(forSubquery: e1, usingIteratorVariable: "x", predicate: predicate)
let expValue = e2.expressionValue(with: nil, context: nil)

通过这些更改,子查询表达式就像魅力一样。