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:]
看起来无法找到键值。我不确定构建子查询表达式有什么问题。
非常感谢任何帮助!
答案 0 :(得分:0)
经过几天的挣扎,我想我得到了一个解决方案!
首先,集合中的类(例如数组中的Person
)必须从NSObject
继承。
public class Person : NSObject {
其次,根据Apple的Developer documentation
也就是说,第三个参数应为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)
通过这些更改,子查询表达式就像魅力一样。