2017-11-04 11 views
0

コアデータデータベースに格納されているエンティティ(「リスト」と呼ばれる)の属性(「名前」と呼ばれる)の値を読み取ろうとしています。私が持っている問題は、その属性の値がnilであり、Stringでなければならないということです。コアデータエンティティの属性値を読み取る

My data model

すべてのリスト・エンティティを取得するための私のコードは次の通りである:これは印刷し

container?.performBackgroundTask { [weak self] context in 
    self?.wordLists = try! List.all(in: context) 
    DispatchQueue.main.async(execute: { 
     print("Main queue available, reloading tableview.") 
     self?.wordListSelector.reloadData() 
    }) 
} 

class func all(in context: NSManagedObjectContext) throws -> [List] { 
    let listRequest: NSFetchRequest<List> = List.fetchRequest() 
    do { 
     let list = try context.fetch(listRequest) 
     print(list) 
     return list 
    } catch { 
     print("error") 
     throw error 
    } 
} 

データベースに3つのリストがあるべきことを私に示して
[<__Words.List: 0x6000000937e0> (entity: List; id: 0xd00000000004000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p1> ; data: <fault>), <__Words.List: 0x600000093a60> (entity: List; id: 0xd00000000008000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p2> ; data: <fault>), <__Words.List: 0x600000093ab0> (entity: List; id: 0xd0000000000c000c <x-coredata://999D0158-64BD-44FD-A0B1-AB4EC03B9386/List/p3> ; data: <fault>)] 

をこれは予想通りです。

Core Date Editor: showing that I have indeed 3 Lists in my database

私はこのような変数を作成しました:

var wordLists: [List] = [] { 
    didSet { 
     print("Detected wordList update, waiting for main queue.") 
     DispatchQueue.main.async(execute: { 
      print("Main queue available, reloading tableview.") 
      self.wordListSelector.reloadData() 
     }) 
    } 
} 

この変数は、私が以前に述べたことのすべて()関数を呼び出すことによって取得したリスト・エンティティを保持しています。

次の2つの方法が私のtableViewを記入します:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    print("numberOfRowsInSection: \(wordLists.count).") 
    return wordLists.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cellIdentifier = "CategoryCell" 
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) 

    print("cellForRowAt: \(indexPath.row) has name \(wordLists[indexPath.row].name).") 
    cell.textLabel?.text = wordLists[indexPath.row].name 

    return cell 
} 

これは、次のように出力されます

Detected wordList update, waiting for main queue. 
Main queue available, reloading tableview. 
numberOfRowsInSection: 3. 
cellForRowAt: 0 has name nil. 
cellForRowAt: 1 has name nil. 
cellForRowAt: 2 has name nil. 

なぜ名前nilでありますか?データはまだ「フォールト」なのでこれはですか?オンラインでトピックを見ることで、私はコアデータがアクセスしようとすると自動的にそのデータをフォールトさせると考えました。私は間違って何をしていますか?

編集:

私は、次のようにdidset変更する場合:それは名前を印刷しない

var wordLists: [List] = [] { 
    didSet { 
     print("Wordlist was updated.") 
     for wordList in wordLists { 
      print(wordList) 
      print(wordList.name) 
     } 
    } 
} 

(オプション( "nameofitem1を"))。 cellForRowAtでは、それでも 'nil'が出力されます。

+0

データソース配列に 'didSet'オブザーバを使用しません**。データを取得した後、テーブルビューを再ロードします。 – vadian

+0

私はそれを変えよう、良い見解:)それ以外は、実際の名前の代わりに「無」の値を得ている理由は何ですか? – Kevin

+0

WordLists配列を実際に配置するコードを表示できますか?あなたが正しいです、CDは自動的に属性にアクセスするときリストオブジェクトのフォールトを発生させる必要があります。しかし、あなたが間違ったスレッドからそれらにアクセスしている場合は、これを行うことができません。あなたの 'didSet'がディスパッチ非同期を使用しているという事実は、実際にスレッドを混在させるかもしれないことを示唆しています。 – pbasdf

答えて

2

あなたはNSFetchedResultsControllerにとってうまくいくように見えます。これは、コメントに示唆されているように混乱する可能性のあるスレッディングにも役立ちます。 NSFetchedResultsController

+0

ああありがとう!私はNSFetchResultsControllerを実装しており、うまくいきます。 – Kevin

関連する問題