Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

Really obscure Foundation (was EOControl) bug

This curious bug will probably only hit those, who write KVC caching schemes. Which means on this planet, this will just interest me, Helge and some unknown guy at Apple :) Sane people don't use same-named instance variables with underscore and without. The bug is, that takeValueForKey: has a different sequence of accessing ivars than valueForKey:.

#import <Foundation/Foundation.h>

@interface Foo : NSObject
{
   id   bar;
   id   _bar;
}
@end


@implementation Foo

- (NSString *) description
{
   return( [NSString stringWithFormat:@"bar=\"%@\"/_bar=\"%@\"", bar, _bar]);
}

@end


static void   test( NSString *storeKey, NSString *queryKey)
{
   Foo   *foo;
   
   foo = [[Foo new] autorelease];
   [foo takeValue:@"VfL Bochum"
           forKey:storeKey];
   NSLog( @"tvfk:\"%@\"+vfk:\"%@\"=%@ (%@)", storeKey, queryKey, [foo valueForKey:queryKey], foo);
   
   foo = [[Foo new] autorelease];
   [foo takeStoredValue:@"VfL Bochum"
                 forKey:storeKey];
   NSLog( @"tsvfk:\"%@\"+vfk:\"%@\"=%@ (%@)", storeKey, queryKey, [foo valueForKey:queryKey], foo);
   
   foo = [[Foo new] autorelease];
   [foo takeValue:@"VfL Bochum"
           forKey:storeKey];
   NSLog( @"tvfk:\"%@\"+svfk:\"%@\"=%@ (%@)", storeKey, queryKey, [foo storedValueForKey:queryKey], foo);
   
   foo = [[Foo new] autorelease];
   [foo takeStoredValue:@"VfL Bochum"
                 forKey:storeKey];
   NSLog( @"%tsvfk:\"%@\"+svfk:\"%@\"=%@ (%@)", storeKey, queryKey, [foo storedValueForKey:queryKey], foo);
}

int main (int argc, const char * argv[]) 
{
   NSAutoreleasePool *pool;
   
   pool = [NSAutoreleasePool new];
   
   test( @"bar", @"bar");
   test( @"bar", @"_bar");
   test( @"_bar", @"bar");
   test( @"_bar", @"_bar");
   
   [pool release];
   return( 0);
}
2006-05-31 01:26:53.902 KVCTest[19582] tvfk:"bar"+vfk:"bar"=(null) (bar="VfL Bochum"/_bar="(null)")
not getting the value back you put in under the same name is not cool
2006-05-31 01:26:53.903 KVCTest[19582] tsvfk:"bar"+vfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.903 KVCTest[19582] tvfk:"bar"+svfk:"bar"=(null) (bar="VfL Bochum"/_bar="(null)")
2006-05-31 01:26:53.904 KVCTest[19582] tsvfk:"bar"+svfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.904 KVCTest[19582] tvfk:"bar"+vfk:"_bar"=(null) (bar="VfL Bochum"/_bar="(null)")
2006-05-31 01:26:53.904 KVCTest[19582] tsvfk:"bar"+vfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.904 KVCTest[19582] tvfk:"bar"+svfk:"_bar"=(null) (bar="VfL Bochum"/_bar="(null)")
2006-05-31 01:26:53.904 KVCTest[19582] tsvfk:"bar"+svfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tvfk:"_bar"+vfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tsvfk:"_bar"+vfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tvfk:"_bar"+svfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tsvfk:"_bar"+svfk:"bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tvfk:"_bar"+vfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tsvfk:"_bar"+vfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tvfk:"_bar"+svfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")
2006-05-31 01:26:53.905 KVCTest[19582] tsvfk:"_bar"+svfk:"_bar"=VfL Bochum (bar="(null)"/_bar="VfL Bochum")