Fix, Base, NSKeyValueCoding (SetValueForKey())

View: New views
4 Messages — Rating Filter:   Alert me  

Fix, Base, NSKeyValueCoding (SetValueForKey())

by Georg Fleischmann-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

here is a fix for NSKeyValueCoding SetValueForKey() to prefer the key  
as is (without leading underscore) before trying with underscore (_key).

My problem: When loading a Nib file with a key named "infoPanel" for  
NSApplication, the value gets set to "_infoPanel" instead, which also  
exists in GNUstep.

Best wishes,
Georg Fleischmann


*** Source/NSKeyValueCoding.m.old 2009-02-28 14:31:08.000000000 +0800
--- Source/NSKeyValueCoding.m 2009-06-23 11:28:56.000000000 +0800
***************
*** 116,143 ****
         if ([[self class] accessInstanceVariablesDirectly] == YES)
    {
     buf[size+4] = '\0';
-  buf[3] = '_';
     buf[4] = lo;
!  name = &buf[3]; // _key
     if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
       {
         buf[4] = hi;
         buf[3] = 's';
         buf[2] = 'i';
!      buf[1] = '_';
!      name = &buf[1]; // _isKey
         if (GSObjCFindVariable(self,
    name, &type, &size, &off) == NO)
    {
     buf[4] = lo;
!  name = &buf[4]; // key
     if (GSObjCFindVariable(self,
       name, &type, &size, &off) == NO)
       {
         buf[4] = hi;
         buf[3] = 's';
         buf[2] = 'i';
!      name = &buf[2]; // isKey
         GSObjCFindVariable(self,
    name, &type, &size, &off);
       }
--- 116,143 ----
         if ([[self class] accessInstanceVariablesDirectly] == YES)
    {
     buf[size+4] = '\0';
     buf[4] = lo;
!  name = &buf[4]; // key
     if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
       {
         buf[4] = hi;
         buf[3] = 's';
         buf[2] = 'i';
!      name = &buf[2]; // isKey
         if (GSObjCFindVariable(self,
    name, &type, &size, &off) == NO)
    {
+  buf[3] = '_';
     buf[4] = lo;
!  name = &buf[3]; // _key
     if (GSObjCFindVariable(self,
       name, &type, &size, &off) == NO)
       {
         buf[4] = hi;
         buf[3] = 's';
         buf[2] = 'i';
!      buf[1] = '_';
!      name = &buf[1]; // _isKey
         GSObjCFindVariable(self,
    name, &type, &size, &off);
       }



_______________________________________________
Bug-gnustep mailing list
Bug-gnustep@...
http://lists.gnu.org/mailman/listinfo/bug-gnustep

Re: Fix, Base, NSKeyValueCoding (SetValueForKey())

by David Ayers-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Am Dienstag, den 23.06.2009, 11:54 +0800 schrieb Georg Fleischmann:
     I. Hi,
>
> here is a fix for NSKeyValueCoding SetValueForKey() to prefer the key  
> as is (without leading underscore) before trying with underscore (_key).
>
> My problem: When loading a Nib file with a key named "infoPanel" for  
> NSApplication, the value gets set to "_infoPanel" instead, which also  
> exists in GNUstep.

I don't have current Cocoa, but the preference to use _infoPanel before
infoPanel is documented KVC behavior.  I would suppose the "bug" would
be the fact that NSApplication has an ivar named "_infoPanel" if such an
ivar does not exist Cocoa.

Cheers,
David

http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html
Default Search Pattern for setValue:forKey:
When the default implementation of setValue:forKey: is invoked for a
property the following search pattern is used:

     1. The receiver’s class is searched for an accessor method whose
        name matches the pattern -set<Key>:.
       
     2. If no accessor is found, and the receiver’s class method
        accessInstanceVariablesDirectly returns YES, the receiver is
        searched for an instance variable whose name matches the pattern
        _<key>, _is<Key>, <key>, or is<Key>, in that order.
       
     3. If a matching accessor or instance variable is located, it is
        used to set the value. If necessary, the value is extracted from
        the object as described in “Representing Data as Objects.”
       
     4. If no appropriate accessor or instance variable is found,
        setValue:forUndefinedKey: is invoked for the receiver.
       

>
> *** Source/NSKeyValueCoding.m.old 2009-02-28 14:31:08.000000000 +0800
> --- Source/NSKeyValueCoding.m 2009-06-23 11:28:56.000000000 +0800
> ***************
> *** 116,143 ****
>          if ([[self class] accessInstanceVariablesDirectly] == YES)
>     {
>      buf[size+4] = '\0';
> -  buf[3] = '_';
>      buf[4] = lo;
> !  name = &buf[3]; // _key
>      if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
>        {
>          buf[4] = hi;
>          buf[3] = 's';
>          buf[2] = 'i';
> !      buf[1] = '_';
> !      name = &buf[1]; // _isKey
>          if (GSObjCFindVariable(self,
>     name, &type, &size, &off) == NO)
>     {
>      buf[4] = lo;
> !  name = &buf[4]; // key
>      if (GSObjCFindVariable(self,
>        name, &type, &size, &off) == NO)
>        {
>          buf[4] = hi;
>          buf[3] = 's';
>          buf[2] = 'i';
> !      name = &buf[2]; // isKey
>          GSObjCFindVariable(self,
>     name, &type, &size, &off);
>        }
> --- 116,143 ----
>          if ([[self class] accessInstanceVariablesDirectly] == YES)
>     {
>      buf[size+4] = '\0';
>      buf[4] = lo;
> !  name = &buf[4]; // key
>      if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
>        {
>          buf[4] = hi;
>          buf[3] = 's';
>          buf[2] = 'i';
> !      name = &buf[2]; // isKey
>          if (GSObjCFindVariable(self,
>     name, &type, &size, &off) == NO)
>     {
> +  buf[3] = '_';
>      buf[4] = lo;
> !  name = &buf[3]; // _key
>      if (GSObjCFindVariable(self,
>        name, &type, &size, &off) == NO)
>        {
>          buf[4] = hi;
>          buf[3] = 's';
>          buf[2] = 'i';
> !      buf[1] = '_';
> !      name = &buf[1]; // _isKey
>          GSObjCFindVariable(self,
>     name, &type, &size, &off);
>        }
>
>
>
> _______________________________________________
> Bug-gnustep mailing list
> Bug-gnustep@...
> http://lists.gnu.org/mailman/listinfo/bug-gnustep
--
David Ayers          Fellow of the Free Software Foundation Europe
http://www.fsfe.org                     http://fellowship.fsfe.org




_______________________________________________
Bug-gnustep mailing list
Bug-gnustep@...
http://lists.gnu.org/mailman/listinfo/bug-gnustep

Re: Fix, Base, NSKeyValueCoding (SetValueForKey())

by Richard Frith-Macdonald-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 23 Jun 2009, at 04:54, Georg Fleischmann wrote:

> Hi,
>
> here is a fix for NSKeyValueCoding SetValueForKey() to prefer the  
> key as is (without leading underscore) before trying with underscore  
> (_key).
>
> My problem: When loading a Nib file with a key named "infoPanel" for  
> NSApplication, the value gets set to "_infoPanel" instead, which  
> also exists in GNUstep.

I'm afraid your 'fix' is actually a request to introduce a bug.  The  
order in which things are searched for is well defined (see http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html)
  and the GNUstep implementation needs to stick to that ordering.  I  
happen to think that the fact that KVC uses names with leading  
underscores  is a design error by Apple, but it's the way things are.

It seems to me that the problem is the choice of key or the choice of  
ivar name, and any fix should be made at one of those rather than  
changing the KVC mechanism.


_______________________________________________
Bug-gnustep mailing list
Bug-gnustep@...
http://lists.gnu.org/mailman/listinfo/bug-gnustep

Re: Fix, Base, NSKeyValueCoding (SetValueForKey())

by Georg Fleischmann-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> I don't have current Cocoa, but the preference to use _infoPanel  
> before
> infoPanel is documented KVC behavior.  I would suppose the "bug" would
> be the fact that NSApplication has an ivar named "_infoPanel" if  
> such an
> ivar does not exist Cocoa.

I wasn't aware of the documentation, so forget about my patch.

However, you are correct, Cocoa does not have an ivar named  
"_infoPanel" in NSApplication.
Will this be changed in GNUstep?

Best wishes,
Georg Fleischmann


$1 = {
   isa = 0x442e0,
   _nextResponder = 0x0,
   _currentEvent = 0x8c2be30,
   _windowList = 0x452404,
   _keyWindow = 0x88ab620,
   _mainWindow = 0x88ab620,
   _delegate = 0x41e000,
   _hiddenList = 0x0,
   _hiddenCount = 0,
   _context = 0x2b13b,
   _appleEventSuspensionID = 0x0,
   obsolete2 = 0x0,
   _unusedApp = 0,
   _running = 1,
   _appFlags = {
     _hidden = 0,
     _RESERVED1 = 0,
     _active = 1,
     _hasBeenRun = 1,
     _doingUnhide = 0,
     _delegateReturnsValidRequestor = 1,
     _deactPending = 0,
     _invalidState = 0,
     _invalidEvent = 1,
     _postedWindowsNeedUpdateNote = 0,
     _wantsToActivate = 0,
     _doingHide = 0,
     _dontSendShouldTerminate = 0,
     _skipWin32DelayedRestoreKeyWindowAfterHide = 0,
     _finishedLaunching = 1,
     _hasEventDelegate = 0,
     _appDying = 0,
     _didNSOpenOrPrint = 0,
     _inDealloc = 0,
     _pendingDidFinish = 0,
     _hasKeyFocus = 0,
     _panelsNonactivating = 0,
     _hiddenOnLaunch = 0,
     _openStatus = 0,
     _batchOrdering = 0,
     _reserved = 0
   },
   _mainMenu = 0x49ea50,
   _appIcon = 0x0,
   _nameTable = 0x0,
   _eventDelegate = 0x0,
   _threadingSupport = 0x4212a0,


On 23.06.2009, at 14:04, David Ayers wrote:

> Am Dienstag, den 23.06.2009, 11:54 +0800 schrieb Georg Fleischmann:
>      I. Hi,
>>
>> here is a fix for NSKeyValueCoding SetValueForKey() to prefer the key
>> as is (without leading underscore) before trying with underscore  
>> (_key).
>>
>> My problem: When loading a Nib file with a key named "infoPanel" for
>> NSApplication, the value gets set to "_infoPanel" instead, which also
>> exists in GNUstep.
>
> I don't have current Cocoa, but the preference to use _infoPanel  
> before
> infoPanel is documented KVC behavior.  I would suppose the "bug" would
> be the fact that NSApplication has an ivar named "_infoPanel" if  
> such an
> ivar does not exist Cocoa.
>
> Cheers,
> David
>
> http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ 
> KeyValueCoding/Concepts/SearchImplementation.html
> Default Search Pattern for setValue:forKey:
> When the default implementation of setValue:forKey: is invoked for a
> property the following search pattern is used:
>
>      1. The receiver’s class is searched for an accessor method whose
>         name matches the pattern -set<Key>:.
>
>      2. If no accessor is found, and the receiver’s class method
>         accessInstanceVariablesDirectly returns YES, the receiver is
>         searched for an instance variable whose name matches the  
> pattern
>         _<key>, _is<Key>, <key>, or is<Key>, in that order.
>
>      3. If a matching accessor or instance variable is located, it is
>         used to set the value. If necessary, the value is extracted  
> from
>         the object as described in “Representing Data as Objects.”
>
>      4. If no appropriate accessor or instance variable is found,
>         setValue:forUndefinedKey: is invoked for the receiver.
>
>
>>
>> *** Source/NSKeyValueCoding.m.old 2009-02-28 14:31:08.000000000 +0800
>> --- Source/NSKeyValueCoding.m 2009-06-23 11:28:56.000000000 +0800
>> ***************
>> *** 116,143 ****
>>          if ([[self class] accessInstanceVariablesDirectly] == YES)
>>     {
>>      buf[size+4] = '\0';
>> -  buf[3] = '_';
>>      buf[4] = lo;
>> !  name = &buf[3]; // _key
>>      if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
>>        {
>>          buf[4] = hi;
>>          buf[3] = 's';
>>          buf[2] = 'i';
>> !      buf[1] = '_';
>> !      name = &buf[1]; // _isKey
>>          if (GSObjCFindVariable(self,
>>     name, &type, &size, &off) == NO)
>>     {
>>      buf[4] = lo;
>> !  name = &buf[4]; // key
>>      if (GSObjCFindVariable(self,
>>        name, &type, &size, &off) == NO)
>>        {
>>          buf[4] = hi;
>>          buf[3] = 's';
>>          buf[2] = 'i';
>> !      name = &buf[2]; // isKey
>>          GSObjCFindVariable(self,
>>     name, &type, &size, &off);
>>        }
>> --- 116,143 ----
>>          if ([[self class] accessInstanceVariablesDirectly] == YES)
>>     {
>>      buf[size+4] = '\0';
>>      buf[4] = lo;
>> !  name = &buf[4]; // key
>>      if (GSObjCFindVariable(self, name, &type, &size, &off) == NO)
>>        {
>>          buf[4] = hi;
>>          buf[3] = 's';
>>          buf[2] = 'i';
>> !      name = &buf[2]; // isKey
>>          if (GSObjCFindVariable(self,
>>     name, &type, &size, &off) == NO)
>>     {
>> +  buf[3] = '_';
>>      buf[4] = lo;
>> !  name = &buf[3]; // _key
>>      if (GSObjCFindVariable(self,
>>        name, &type, &size, &off) == NO)
>>        {
>>          buf[4] = hi;
>>          buf[3] = 's';
>>          buf[2] = 'i';
>> !      buf[1] = '_';
>> !      name = &buf[1]; // _isKey
>>          GSObjCFindVariable(self,
>>     name, &type, &size, &off);
>>        }
>>
>>
>>
>> _______________________________________________
>> Bug-gnustep mailing list
>> Bug-gnustep@...
>> http://lists.gnu.org/mailman/listinfo/bug-gnustep
> --
> David Ayers          Fellow of the Free Software Foundation Europe
> http://www.fsfe.org                     http://fellowship.fsfe.org
>
>
>



_______________________________________________
Bug-gnustep mailing list
Bug-gnustep@...
http://lists.gnu.org/mailman/listinfo/bug-gnustep