2016-10-17 7 views
1

Swift 3で新しいNSExpresionタイプSubquery expressionが導入されました。私はプレイグラウンドでそれを使用しようとしましたが、動作させることができませんでした。私はMyPlaygroundでSourcesフォルダ内のクラスを作成しNSExpressionサブクエリの使用

まず:MyPlaygroundで

// 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 
    } 
} 

、コレクション式がE1として作成されます(私は、集計およびフォーマット式の両方を試してみましたすべては、コレクションの表現ですが、後半部分で失敗しました)次に

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} 

E2が作成されるサブクエリ式:

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

最後に私が表現から生じる取得しようとしたとき、エラーが発生しました:次のように

let expValue = e2.expressionValue(with: nil, context: nil) 
// Error 

エラーメッセージは次のとおりです。これは、キーと値のように見える

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

を見つけることができません。私はサブクエリ式を構築するのに間違っているかどうかはわかりません。

大変感謝しています。

答えて

0

日々の苦労の末、私は解決策があると思います!

まず、コレクション内のクラス(Personなど)を配列内でNSObjectから継承する必要があります。

public class Person : NSObject { 

第二に、つまりAppleのDeveloper documentation

enter image description here

によると、3番目のパラメータは(StringAnyであるにも関わらず?)NSPredicateタイプでなければなりません。更新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) 

、サブクエリ式は魔法のように動作します。

関連する問題