_NSBindingAdaptor: Under ytan ... del 2

[editerad 081023, hade missat vad ba var satt till]
Fortsättning på del 1.

Resan fortsätter in i en av AppKits hemliga klasser. Hittar vi något?

Ola Bäckström 9 juli 2008

(för stämningens skull, lägg till musik från Doktor Drøvels hemlighet)

Vad kan vi finna ut om _NSBindingAdapter?

Jo, vår fina Nu är en lispinterpreter som ligger alldeles ovanpå Obj-Cns runtime . Vi kan lätt lista vilken klass som adaptern ärver från:

%(set ba (y _bindingAdaptor))
<_NSBindingAdaptor:34c590>
%
% (ba superclass)
NSObject
% 

ba sätts alltså till y:s _NSBindingAdapter. ba är alltså ett ganska enkelt objekt… som speciellt inte ärver från NSBinder som vi tidigare funderat runt.

Nu introducerar egna klasser (t ex NuCell som används för att bygga listor på klassiskt lispmanér) men Nu-språket lägger också till en del finnesser på existerande AppKit klasser. Speciellt på NSObject finns en del nya grejer. De två vi bryr oss om är:

+ (NSArray *) instanceMethodNames
+ (NSArray *) instanceVariableNames

Helt fantastiska funktioner för introspektion… Vi kan be en klass att redogöra vilka instansmetoder och instansvariabler som objekt av den klassen kan agera på.

(För att det verkligen ska gå in så repeterar jag) … vi kan alltså få reda på vilka instansvariabler vilken klass som helst lägger till – även Apples hemliga AppKitklasser.

Adapterns metoder

Det vi vill undersöka är _NSBindingAdapter, så vi slår


% ((ba instanceMethodNames) list)
("_discardEditingForAllBinders" 
"_editor:didChangeEditingState:bindingAdaptor:" 
"_handleValidationError:description:inEditor:errorUserInterfaceHandled:bindingAdaptor:" 
"_objectDidTriggerAction:bindingAdaptor:" 
"_validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:bindingAdaptor:" 
"addBinder:" 
"binders" 
"boundOutlineView:isItemExpandable:" 
"browser:createRowsForColumn:inMatrix:"
"browser:selectRow:inColumn:"
"browser:willDisplayCell:atRow:column:"
"collectionView:didChangeToSelectionIndexes:" 
"contentBinder"
"controller:didChangeToFilterPredicate:"
"controller:didChangeToSelectionIndexPaths:"
"controller:didChangeToSelectionIndexes:"
"controller:didChangeToSortDescriptors:" 
"dealloc" 
"defaultSortDescriptorPrototypeForTableColumn:" 
"drawer:didChangeToState:" 
"editableBinder" 
"editorDidBeginEditing:" 
"editorDidEndEditing:" 
"enabledStateForMenuItem:" 
"finalize" 
"handleValidationError:description:inEditor:errorUserInterfaceHandled:" 
"init" 
"numberOfRowsInTableView:" 
"objectDidTriggerAction:" 
"objectDidTriggerDoubleClickAction:" 
"outlineColumn:willDisplayCell:row:" 
"outlineColumn:willDisplayOutlineCell:row:" 
"outlineView:child:ofItem:" 
"outlineView:didExpandItem:" 
"outlineView:numberOfChildrenOfItem:" 
"outlineView:willCollapseItem:" 
"outlineView:willDisplayCell:forTableColumn:row:"
"outlineView:willDisplayOutlineCell:forTableColumn:row:" 
"referenceBinder" 
"removeBinder:" 
"searchFieldCellOrControlDidClearRecents:" 
"searchMenuTemplate" 
"selectionMechanismWasDismissed:" 
"tabView:didSelectTabViewItem:"
"tableColumn:didChangeToWidth:"
"tableColumn:willDisplayCell:row:"
"tableView:didChangeToSelectedRowIndexes:"
"tableView:didChangeToSortDescriptors:"
"tableView:shouldEditTableColumn:row:" 
"tableView:updateVisibleRowInformation:"
"tableView:willDisplayCell:forTableColumn:row:"
"updateInvalidatedFont:forObject:"
"updateInvalidatedObjectValue:forObject:"
"updateInvalidatedTextColor:forObject:"
"validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:"
"window:didChangeToVisibleState:" 
"windowDidResize:")
%

Ojojoj. (För att nush ska skriva ut resultatet fint har vi förvandlat returvärdet från typen NSArray till en lista.)
Det som, för mig, speciellt sticker ut är

tableColumn:willDisplayCell:row:
tableView:didChangeToSelectedRowIndexes: tableView:didChangeToSortDescriptors: 
tableView:shouldEditTableColumn:row: 
tableView:updateVisibleRowInformation:
tableView:willDisplayCell:forTableColumn:row:

Som verkar indikera på att _NSBindingAdaptor kan agera som NSTableViews delegat, och på så sätt förse “bindningsmekaniken” med information om vad själva tabellkontrollen (vyn i MVC) håller på med. Vidare…

"editorDidBeginEditing:" 
"editorDidEndEditing:" 

verkar indikera på att _NSBindingAdaptor kan ta en roll i koordination av vyer som editerar samma objekt, (se NSEditorRegistration). Notera den lilla skillnaden att metoderna ovan börjar med editorDid... medan de i det publicerade NSEditorRegistration-protokollet börjar på objectDid....

Adapterns instansvariabler

Nu slår vi

% ((ba instanceVariableNames) list)
("_binders" "_contentBinder" "_editableBinder" "_referenceBinder")
% 

Aha… till varje bundet objekt (i vårt fall y) krokas en bindningsadapter på som i sin tur håller ordning på 4 saker. Getters finns, men setters är inte helt lätt att finna ur den långa listan ovan:

  1. _binders hör antagligen ihop med getter binders och metoden addBinder:.
  2. _contentBinder hör nog ihop med gettern contentBinder.
  3. _editableBinder hör nog ihop med gettern editableBinder
  4. _referenceBinder hör nog ihop med gettern referenceBinder

Cirkeln sluts

I vårt fall, med objektet y bundit mot x, så är alla de tre sista tomma (nil) men den första pekar på ett nytt odokumenterat objekt, på adressen 0x3655f0:

% ((ba binders) list)
(<NSObjectParameterBinder: 0x3655f0>{object: <TTCrap: 0x3435f0>, bindings: attr=val})
%
% (set binderOne ((ba binders) objectAtIndex:0))
<NSObjectParameterBinder:3655f0>
% (binderOne description)
"<NSObjectParameterBinder: 0x3655f0>{object: <TTCrap: 0x3435f0>, bindings: attr=val}"
% (binderOne superclass)
NSBinder
%

En binder av typen NSObjectParameterBinder håller reda på att vi har knutit ihop attributen attr och val. Detta är en av de 13 vi tidigare sett via F-scripts klassbrowser

Arbetshypotes

Jag tror att varje objekt som binds mot ett annat får en bindningsadaptor tillkopplad. Sedan, för varje bindning som görs läggs ett binder-objekt (subklassad från NSBinder) till i listan ovan. För objekt som NSTableView som har många bindingsmöjligheter (content, isEditable etc) kan det alltså kopplas till många NSBinders. Just nu ser min skiss ut så här:

Det är osäkerheter i bilden ovan.
Nu stoppar vi här. Andas. Nu ska jag dyka in i vad dessa NSBinders gör! Kanske en senare artikel.

,

---
---