2016-04-20 17 views
2

Versuchen, das ausgewählte Segment eines NSToolbarItem, das ist NSSegmentedControl über Verbindungsbindung zu einer Eigenschaft (optionSegment). Subklassen die Fenstersteuerung als solcheVerhindert Cocoa-Verbindungsbindung zu NSToolbarItem das Deinitialisieren?

class MyWindow: NSWindowController { 
    dynamic var optionSegment: Int = 0 

    override func windowDidLoad() { 
     super.windowDidLoad() 
    } 
} 

Alternativ setzen die optionSegment Eigenschaft in der NSDocument Unterklasse und dass binden. Jede Arbeit. Das Problem ist, dass mit dieser Bindung, oder scheinbar jede Bindung an NSToolbarItem, keines meiner Objekte (Ansichten, View-Controller, Dokument, etc) deinitialisieren wird. Mit einer Bindung tun sie das nicht. Entferne die Bindung und sie tun es.

Irgendwelche Ideen, warum dies so sein könnte? Vorschläge? Ziemlich ratlos.

Vielen Dank!

+0

Sie beabsichtigen zu entziehen? [Ich musste feststellen, dass ich Bindings explizit abbrechen musste, um die Freigabe des Fenstercontrollers zu veranlassen] (http://stackoverflow.com/questions/23944436/should-i-need-to-unbind-cocoa-bindings-in-dealloc -of-Fenstercontroller). Es sollte nicht so sein, aber es ist so. An dieser Stelle würde ich wahrscheinlich zurückgehen und sicherstellen, dass alle meine IBOutlets "schwach" sind, um sicherzustellen, dass die einzigen "starken" Referenzen in der Ansichtshierarchie sind. Sie könnten * ein starkes IBOutlet haben, das verhindert, dass die Dealloc die View-Hierarchie aufplustern, obwohl ich mir nicht sicher bin, warum das nur für die Bindung wichtig wäre. – stevesliva

+0

Es ist schnell, ich beziehe mich also auf die Deinit-Methode der Klassen. Ich werde in den von Ihnen bereitgestellten Link schauen und sehen, was innerhalb von Swift möglich ist. Vielen Dank! – JKaz

+0

Ohne Bindungen wird die Deinit {} -Methode des Fenster-Controllers zuerst aufgerufen, und diese wird durch den Ansichts-Controller, das Dokument, die Ansichten, die Daten usw. gekippt. Jedes Objekt erhält seinen Inhalt in logischer Reihenfolge. Mit nur einer einzigen Eigenschaft, die an ein einzelnes NSToolbarItem gebunden ist, wird der Deinit des Fenstercontrollers nicht aufgerufen, und dann auch keiner der anderen, so dass der Code nicht an die Stelle gelangt, an der ich den Code abreißen könnte Bindungen. Es gibt keine starken IBOutlets, die, wie Sie betonen, auch ein Faktor ohne Bindungen wären. – JKaz

Antwort

1

Wie von Willeke vorgeschlagen, war toolbarItem.view der Weg zum Erfolg. Ich muss sagen, dass mir die Hierarchie der Objekte nicht immer klar ist, aber .view schien die einzige Möglichkeit zu sein, als ich über Nacht auf die ToolbarItem-Hooks schaute und Willekes Vorschlag bestätigte es. Die Apple-Dokumentation zur Bindung erwähnt es als unsere Verantwortung, einige Objekte zu lösen, während es andere unbändig macht. Hier ist der Code, den ich in meine NSDocument-Unterklasse gesetzt habe, um alles zu lösen, und der View-Controller wird nun deinitialisiert.

func windowWillClose(notification: NSNotification) { 
    let wcs = self.windowControllers 
    if wcs.count == 0 { return } 
    let wc = wcs[0] 
    let toolbar = wc.window?.toolbar 
    if toolbar != nil { 
     let items = toolbar!.items 
     for item in items { 
      let v = item.view 
      if v != nil { 
       // print(v?.className) 
       let objects = v!.exposedBindings 
       for object in objects { 
        // print(object + " " + item.label + " " + v!.className) 
        v!.unbind(object) 
       } 
      } 
     } 
    } 
} 

Dies war einer der verwirrendsten Konzepte, die ich in laufen haben - so viele bewegliche Teile - und dank Willeke & stevesliva für den Dialog, der zu einer Lösung schlängelte.

Von NSObject (NSKeyValueBindingCreation):

Alle Standard-Bindungen auf AppKit Objekte (Ansichten, Zellen, Tabellenspalten, Controller) ihre Bindungen automatisch lösen, wenn sie deallokierten sind, aber wenn Sie Schlüsselwert erstellen Bindungen für andere Art von Objekte, müssen Sie sicherstellen, dass Sie diese Bindungen vor Freigabe entfernen (beobachtete Objekte haben schwache Referenzen auf ihre Beobachter, so Controller/Modellobjekte weiter Referenzierung und Messaging die Objekte, die an sie gebunden waren).

+0

Gute Arbeit graben, die unverbindliche Blockquote. Klingt wie wenn Sie ein Steuerelement an etwas anderes als einen Controller binden, sind alle Wetten für die Entbindung automatisch ablaufen. – stevesliva