2016-08-04 40 views
0

In meiner Mac-App präsentiere ich ein Login-Fenster (in einem NSViewController über ein sheet Segment). Es gibt eine OK-Taste, und wenn ich drücke, mache ich einen Netzwerkanruf. Am Ende des Netzwerkaufrufs mache ich ein paar Sachen und lehne das Blatt dann ab. Das Blatt verschwindet tatsächlich.Cocoa-Absturz von nicht existierendem NSViewController

Jetzt zurück auf meinem NSViewController, der das Login-Fenster präsentierte Ich fange an, ein NSTableView auf und ab scrollen. Ich erhalte eine CoreAnimation-Warnung über nicht übergebene CATransaction-Nachrichten. Manchmal verursacht es einen Absturz, manchmal nicht.

Dies ist der Stack-Trace ich:

Coreanimation: Warnung, gelöscht Gewinde mit ungebundener CATransaction; erstellt:
0 Quartz 0x00007fff8befe69a _ZN2CA11Transaction4pushEv + 318
1 Quartz 0x00007fff8befe19a _ZN2CA11Transaction15ensure_implicitEv + 276
2 Quartz 0x00007fff8bf04719 _ZN2CA5Layer13thread_flags_EPNS_11TransactionE + 37
3 Quartz 0x00007fff8bf04668 _ZN2CA5Layer4markEPNS_11TransactionEjj + 64
4 Quartz 0x00007fff8bf0612b _ZN2CA5Layer25set_needs_display_in_rectERK6CGRect + 333
5 Quartz 0x00007fff8bf05fdc - [ CALayer setNeedsDisplayInRect:] + 25
6 AppKit 0x00007fff91aff2e8 _NSBackingLayerSetNeedsDispla yInRect + 319
7 AppKit 0x00007fff91aff1a3 - [_ NSBackingLayer setNeedsDisplayInRect:] + 61
8 Quartz 0x00007fff8bf05f9d - [CALayer setNeedsDisplay] + 62
9 AppKit 0x00007fff91aff98b - [NSView (NSInternal) _setLayerNeedsDisplayInViewRect:] + 606
10 AppKit 0x00007fff91acd88e NSViewSetNeedsDisplayInRect + 945
11 AppKit 0x00007fff91acd4d6 - [NSView setNeedsDisplayInRect:] + 48
12 AppKit 0x00007fff91acd2ed - [NSView setNeedsDisplay:] + 81
13 AppKit 0x00007fff91e48905 - [NSProgressIndicator setDoubleValue:] + 338Traffic System 14 Digitale 0x0000000100063fba _TFFFC22Digital_Traffic_System19LoginViewControllerP33_5EDE918279C9F0B1F3EE7B966507D60715okButtonPressedFCSo8NSButtonT_U_FGSqPs9AnyObject__T_U_FTSSSi_T_ + 266
15 Digital-Traffic System 0x0000000100064282 _TTRXFo_oSSdSi_dT__XFo_iTSSSi__iT__ + 66

Linie 14 zeigt meine "okButtonPressed" Methode aus dem LoginViewController, und dann auf der Linie 13 Ich sehe es im Gespräch über meinen NSProgressIndicator versuchen, einen Wert festgelegt zu haben. Es sollte nicht einmal an dieser Stelle existiert :(

Hier ist, was das Verfahren wie folgt aussieht:

final class LoginViewController: NSViewController, HasMOC { 
    @IBOutlet private weak var progressBar: NSProgressIndicator! 

    @IBAction private func okButtonPressed(sender: NSButton) { 
     sender.enabled = false 

     commitEditing() 

     // Webserver uses Alamofire to make async web calls. 
     Webserver.sharedInstance.startupData { 
      [unowned self] data in 

      defer { sender.enabled = true } 

      guard let json = data as? [[[String : AnyObject]]] else { 
       NSAlert.okWithMessage("Failed to download data from web server.") 
       return 
      } 

      self.progressBar.hidden = false 

      DataImporter.importData(json, managedObjectContext: self.managedObjectContext, 
       onType: { 
        [weak self] str, max in 
        self?.progressBar.doubleValue = 0 
        self?.progressBar.maxValue = Double(max) 
        self?.progressText.stringValue = str 
       }, onEntity: { 
        [weak self] in 
        self?.progressBar.incrementBy(1) 
       }, onComplete: { 
        [weak self] in 
        (NSApplication.sharedApplication().delegate as! AppDelegate).showHideReportMenu() 

        self?.onLoginSuccessful?() 

        self?.dismissController(nil) 
      }) 
     } 
} 

ich im Anfangsblock unowned verwenden, da dieses Fenster nicht, wenn der Web-Aufruf zurückgegeben hat verschwinden. es gibt keine Taste manuell weg gehen.

+0

Ich habe gerade Druckanweisungen in onType, onEntity und onComplete hinzugefügt. Der onComplete ruft an und das Blatt verschwindet. Wenn ich anfange, die Tabelle zu scrollen und den Stack-Trace zu erhalten, druckt es keine dieser drei Nachrichten neu. – Gargoyle

Antwort

0

Ihr Service Rückrufe ausgeführt werden, auf nicht-UI-Thread und Sie versuchen, Elemente der Benutzeroberfläche zu aktualisieren.

Sie sollten jene auf die Main Queue bewegen, dh:

NSOperationQueue.mainQueue().addOperationWithBlock { 
     [unowned self] in 
     //Your code changing UI elements, kicking animations .e.t.c 
    } 
+0

Danke. Anscheinend lief der Datenimporteur in einem anderen Kontext. – Gargoyle