2017-02-28 6 views
0

私はこの実現可能性をテストするためにこのダミーの設定をしています。アイデアは: ゲームが最初に起動したら、私はCoreDataを使ってデータベースに(plistsに保存されている)たくさんのデータをコピーする必要があります。私はグローバルなバックグラウンドキューの中でこれをやりたがっています(つまり、UIはまだ応答しています)。私的なmanagedObjectContext(バックグラウンドスレッドで作成)によって作成されたCoreDataオブジェクトにアクセス

私がやろうものです:

appDelegate.persistentContainer.performBackgroundTask { (managedObjectContext) in 
    GameSetupController.setup(withManagedObjectContext: managedObjectContext) 
} 

私はbackgroundTaskを開始し、私のGameSetupController上のメソッドを呼び出します。

static func setup(withManagedObjectContext managedObjectContext: NSManagedObjectContext) { 
    let startCoords = Coordinates(atQuadrant: 153, galaxy: 42, system: 3, using: managedObjectContext) 
    let startPlanet = Planet(atCoordinates: startCoords, withName: "Planet 1", using: managedObjectContext) 
    let startBase = Site(atPlanet: startPlanet, withName: "Name of base", belongingToPlayer: true, using: managedObjectContext) 

    // Game is a singleton 
    Game.shared.currentSite = startBase 

    do { 
     try managedObjectContext.save() 
    } catch let error as NSError { 
     fatalError("Couldn't save to database. Error: \(error.debugDescription)") 
    } 
} 

Game singletonは、ユーザが現在位置するようSiteとして、現在のゲームのプロパティを格納するために使用されています。それはこのようになります。

バックグラウンドタスクが終了した後、Game.shared.currentSite(メインキューから)を印刷したいとします。

Optional(<Site: 0x17008c080> (entity: Site; id: 0xd000000000100004 <x-coredata://5D8B1335-5F8F-4E66-BC3F-DA7C7AA2B54B/Site/p4> ; data: <fault>)) 

通常(それはCoreDataの私の理解だが)、あなたはそれを発射し、データをロードfaultedNSManagedObjectにアクセスする場合:それは私が何を得るのです。しかし、ここでは、これは起こりません。私は(そこに宣言していますmanagedObjectContextを使用して)メインキューにGameSetupController.setup(withManagedObjectContext: managedObjectContext)を実行する場合

しかし、私はこれを取得:

私が欲しいものだ
Optional(<Site: 0x170092610> (entity: Site; id: 0xd000000000140004 <x-coredata://5D8B1335-5F8F-4E66-BC3F-DA7C7AA2B54B/Site/p5> ; data: { 
    belongsToPlayer = 1; 
    buildings =  (
    ); 
    coordinates = "0xd000000000140000 <x-coredata://5D8B1335-5F8F-4E66-BC3F-DA7C7AA2B54B/Coordinates/p5>"; 
    events =  (
    ); 
    name = "Main Base I"; 
    planet = "0xd000000000140002 <x-coredata://5D8B1335-5F8F-4E66-BC3F-DA7C7AA2B54B/Planet/p5>"; 
    resources = nil; 
    spaceships =  (
    ); 
})) 

。バックグラウンドキューでprivate managedObjectContextを使用するとき、この結果を得るにはどうすればよいですか?それも可能ですか?

コードや情報が必要な場合はお知らせください。ありがとう!

答えて

1

使用している方法、performBackgroundTask実際

はNSPrivateQueueConcurrencyTypeに設定concurrencyTypeで新しいNSManagedObjectContextを作成します。

Source

それは、このコンテキストはおそらくあなたがGame.shared.currentSiteオブジェクトを印刷時間によって割り当て解除を取得することを意味します。そして、これはもはや既存の文脈の中に作られて以来、それを断絶する方法はない。

基本的には、バックグラウンドスレッドでデータベースにデータを取り込むというアイデアは良いことですが、アプリが実行されている間はメインコンテキストからGame.shared.currentSiteオブジェクトを取得するだけで済みます。

UPDATE:あなたはCoreDataオブジェクトをデバッグするprintメソッドを使用している場合

また、それは非障害にそれらを起こさないことを覚えておいてください。代わりに、いくつかのプロパティを印刷してみることができます。フォルトがうまくいかなかった場合は表示されます。

+0

大丈夫です。新しい 'NSManagedObjectContext'を作成しようとしていることは分かっていましたが、メインのキューからメインの' managedObject'の子として作成されると思いました。だから私はそれがうまくいくと思ったのです。それが知っていないことを知っていればよい:D。それから私は 'サイト'が取り出すべき 'ゲームのシングルトン'を伝える方法を見つけなければならないでしょう。たぶん 'startBase'の' ObjectID'を使って? – Quantm

+0

実際、この新しい背景コンテキストは、AppDelegateの 'persistentContainer'からの' viewContext'の子です。しかし、これは割り当て解除される別のコンテキストであるという事実を変更しません。 'Game'シングルトンの' Site'を取得するアイデアについては、 'objectID'プロパティを使用するのが最も簡単で安全なアプローチになると思います。 – user3581248

+0

よかった、ありがとう。 'objectID'を' Game'シングルトン(コンテキストを保存した後)に格納しようとしましたが、 'managedObjectContext.object(with:)'を使ってメインキューの 'currentSite'を取り出しました。しかし、それが戻ってくるオブジェクトはまだ間違いです。なぜ私は分からない。 – Quantm

関連する問題