2016-03-28 9 views
0

vor kurzem habe ich ein Problem, das ich nicht erklären kann. Also habe ich eine Klasse DocumentContext, die ein einzelnes Dokument (NSManagedObject) enthält. Der Code für diese KlassenNSManagedObjectContext Deadlock

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") 
    } 

} 

sind Jetzt ist hier der seltsame Teil, ich habe zwei Anrufe auf dem Hauptthread innerhalb des Viewcontroller:

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

Und kurz nach

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

Es funktioniert wie erwartet, aber wenn ich den letzten Anruf zu performBlockAndWait ändern, hängt die ganze App schön. Ich drückte Pause und sah, dass anscheinend dieser Anruf self.context.document.imagePairs? durch den Semaphor blockiert wird, so scheint es, dass es durch den Haupt-Thread oder etwas blockiert ist. Irgendwelche Ideen, warum es etwas auf dem Hauptthread tun wird? Von meinem Punkt sollte es offensichtlich im ManagedObjectContext-Thread bleiben.

Antwort

0

Okay - gerade die Sekunde, bevor ich Postknopf drückte, realisierte ich die Antwort zu meiner eigenen Frage)) Wird es hier lassen, wenn jemand auf ähnliches Problem trifft. Das Problem war - mein Elternkontext wurde mit MainConcurrencyType instanziiert. Als mein Code anfing, die Relation zu holen, ging er durch diesen Kontext und daher nahm ich die Hauptwarteschlange an. Sobald ich den Nebenläufigkeitstyp auf privat geändert habe, ist der Fehler weg.