2017-08-07 13 views
0

レルムからどのような種類のデータを取得するための汎用関数を構築しましたが、うまくいくようです。結果<Object>が返されたときにRealmswift汎用関数呼び出しがクラッシュします

func getData<T: Object>(withFilter: String) -> Results<T>? { 
    if !checkRealm(){return nil} 
    return realm!.objects(T.self).filter(withFilter) 
} 

この機能を使用してデータを削除する方法はわかりません。 私の削除機能は以下の通りです:これはエラー、添付怒鳴るになり

func removeData(withFilter: String) { 

     let dataToDelete: Results<Object>? = getData(withFilter: withFilter) 
     // *** The above line crashes the app *** 

     if let dataToDeleteUnwrapped = dataToDelete{ 
      try? realm!.write { 
       realm!.delete(dataToDeleteUnwrapped) 
      } 
    } 
} 

Results<Object>?はアプリをクラッシュさせますが、Results<MyCustomObject>?は問題なく動作しますが、データの削除機能は一般的ではありません。

Terminating app due to uncaught exception 'RLMException', reason: 'Object type 'RealmSwiftObject' is not managed by the Realm. If using a custom `objectClasses`/`objectTypes` array in your configuration, add `RealmSwiftObject` to the list of `objectClasses`/`objectTypes`.' 

は、私はこの1つを解決するための素敵な短い方法がある確信しているが、私はそれをfiggureすることはできませんので、任意のヘルプは大歓迎です。

答えて

2

Resultsは、複数のクラスのインスタンスを保持することはできません。すべての要素が同じ型である必要があります。したがって、Results<Object>はコレクションの有効な型ではありません。

getDataの現在の実装は間違っています。関数内のどこにでもジェネリックタイプTは使用しないでください。ジェネリック関数の入力引数には、汎用型を指定する必要があります。 Resultは1つのタイプしか保持できず、すべてのタイプに固有のプロパティがあるため、特定のタイプの述部しか使用できないため、とremoveDataの両方をObjectから継承する特定のRealmタイプで呼び出す必要があります。

Realmに、指定された述語を持つクエリを実行するための正しい汎用実装getDataです。

func getData<T:Object>(ofType: T.Type, withFilter: String) -> Results<T>? { 
    if !checkRealm(){return nil} 
    return realm!.objects(T.self).filter(withFilter) 
} 

あなたはこのようにそれを呼び出す(次の例では、試験し、Realmウェブサイトから例のプロジェクトでの遊び場と協力しています):一般的な機能がいかに見て

let people = getData(ofType: Person.self, withFilter: "[email protected] > 1 && spouse != nil") 
people?.first?.name //prints Jennifer when called after adding the objects to realm, but before deleting them in the example project 

タイプの制約があるRealmで使用されている場合は、削除機能も更新する必要があります。実際のオブジェクトに結果を変換する

+0

これは、デバッガで例外ブレークポイントを設定し、同じエラー – Thodoris

+0

をスローしての種類を確認して使用する方法'Result'の要素です。 'getData'が動作しているかどうかチェックしましたか?実際には正確な型で呼び出すのではないようです。これは、汎用関数を作成する方法ではありません。 'T'は、単一のクラスのインスタンスをフェッチするために' getData'に送る入力引数の型制約です。 –

+0

私が質問に言及したように、{Results ?}のように型を定義するとうまくいくので、実際には{removedata}関数を呼び出すときに結果の型を宣言できますか? {removedata}関数を各タイプに1つずつ追加します。 – Thodoris

0

使用この拡張

extension Results { 
     func toArray<T>(ofType: T.Type) -> [T] { 
      var array = [T]() 
      for i in 0 ..< count { 
       if let result = self[i] as? T { 
        array.append(result) 
       } 
      } 
      return array 
     } 
    } 

コード

let orjObjs = realm.objects(UrObj.self).toArray(ofType: UrObj.self) as [UrObj] 
+1

まず、 'Result'コレクションを' Array'に変換する必要はありません。第2に、 'Result'から' Array'への変換は組み込みの 'Array'初期化子' Array(Result ) 'を使って行うことができるので、あなたの拡張は全く必要ありません。具体的には、 'Array(realm.objects(MyType.self))'は 'Array '型のオブジェクトを返します。 –

関連する問題