He tenido un gran problema al implementar enlaces para mi propia subclase NSView. Funciona, pero hay problemas con los ciclos de retención cuando se vincula al propietario del archivo desde un archivo nib. Después de leerlo un poco, descubrí que Apple tuvo el mismo problema hace unos años, pero lo arregló con alguna clase mágica no documentada (NSAutounbinder).¿Se pueden implementar manualmente las uniones Cocoa?
Hay una larga discusión del problema del ciclo de retención aquí http://www.cocoabuilder.com/archive/message/cocoa/2004/6/12/109600. La solución consiste en desvincular todas las vinculaciones antes de que el controlador de ventana sea lanzado, no antes de que sea desasignado, en un lugar como windowWillClose :. Esto me parece un truco innecesario.
Mi pregunta es esta: ¿hay alguna forma de hacer enlaces personalizados que funcionen tan bien como los creados por Apple, sin usar características no documentadas? ¿Voy por esto de la manera incorrecta?
ACTUALIZACIÓN 2: He encontrado una solución que permite que los enlaces implementados manualmente funcionen exactamente como los enlaces de Apple. Aprovecha la clase NSAutounbinder indocumentada, sin utilizar realmente las características no documentadas. Voy a publicar la solución más tarde hoy.
ACTUALIZACIÓN: He intentado usar exposeBinding:
, y no parece hacer ninguna diferencia. Sin embargo, la implementación NSObject
de bind:toObject:withKeyPath:options:
funciona a medias. Propociona cambios de bindee a aglutinante (es decir, del modelo/controlador a visualizar), pero no funciona de la manera opuesta. Además, aunque obviamente se está observando el bindee, observeValueForKeyPath:ofObject:change:context:
nunca se activa.
Proyecto de ejemplo aquí: http://www.tomdalling.com/wp-content/BindingsTest.zip
documentación de Apple indica que usted, de hecho, tiene que anular bind:toObject:withKeyPath:options:
para implementar las consolidaciones manuales. Ver aquí: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html
Nota al margen: He investigado cómo funciona el NSAutounbinder indocumentado, y esto es lo que sé.
Cuando se crea un enlace a un NSWindowController, el objeto enlazado es en realidad un NSAutounbinder que se adquiere del NSWindowController con - [NSWindowController _autounbinder]. NSAutounbinder es un proxy no retenible para el objeto NSWindowController. No se retiene para evitar el problema del ciclo de retención.
Cuando - [Liberación de NSWindowController] se llama y retainCount == 1, El NSAutounbinder desenlaza todos los enlaces a sí mismo. Esto garantiza que no haya punteros colgantes para el objeto antes de desasignarse.
Mientras CocoaBuilder está caído, puede encontrar el hilo relevante en http://lists.apple.com/archives/cocoa-dev/2004//Jun/msg00835.html – s4y