2016-03-28 17 views
0

最近、説明できない問題が発生しました。だから私はそれの中に単一のドキュメント(NSManagedObject)を保持するクラスDocumentContextを持っています。NSManagedObjectContextデッドロック

context.performBlock { [unowned self] in 
     let pairs = self.context.document.imagePairs?.array as? [ImagePair] 
    } 

、まもなくそれが動作

context.performBlock { [unowned self] in 
     let fields = self.context.document.fields 
    } 

後:これらのクラスは

extension Document { 

    @NSManaged var title: String? 
    @NSManaged var type: String? 
    @NSManaged var created_at: NSDate? 
    @NSManaged var fields: NSSet? 
    @NSManaged var imagePairs: NSOrderedSet? 

} 

class DocumentContext: NSManagedObjectContext { 

    var document: Document! 

    convenience init(document: Document? = nil) { 
     self.init(concurrencyType: .PrivateQueueConcurrencyType) 
     self.parentContext = document?.managedObjectContext ?? NSManagedObject.defaultContext 
     self.performBlockAndWait { [unowned self] in 
      if let doc = document { 
       let id = doc.objectID 
       self.document = self.objectWithID(id) as! Document 
      } else { 
       self.document = Document.create(self) 
      } 

     } 
    } 

    override init(concurrencyType ct: NSManagedObjectContextConcurrencyType) { 
     super.init(concurrencyType: ct) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 

あるため、コードは今ここに、私はViewControllerを内側メインスレッド上に2つのコールを持っている、奇妙な部分です期待どおりに、私はperformBlockAndWaitに最後の呼び出しを変更すると、アプリ全体がうまくハングアップします。私は一時停止を押して、明らかにこの電話self.context.document.imagePairs?がセマフォによってブロックされているのを見たので、それはメインスレッドなどによってブロックされているように見えます。メインスレッドで何かをする理由は?私の考え方では、明らかにManagedObjectContextスレッドにとどまるはずです。

答えて

0

私は自分の質問への答えを実現したポストボタンを押す前にちょうど2番目))誰もが同様の問題に遭遇するなら、ここに残しておきます。問題は、私の親コンテキストがMainConcurrencyTypeでインスタンス化されたことです。私のコードが関係を取得し始めたとき、それはこの文脈を通り抜けていたので、私は主な待ち行列を推測していました。並行性のタイプをprivateに変更するとすぐに、バグはなくなりました。