Index: src/OFObject+KeyValueCoding.m ================================================================== --- src/OFObject+KeyValueCoding.m +++ src/OFObject+KeyValueCoding.m @@ -46,12 +46,37 @@ { SEL selector = sel_registerName([key UTF8String]); const char *typeEncoding = [self typeEncodingForSelector: selector]; id ret; - if (typeEncoding == NULL) - return [self valueForUndefinedKey: key]; + if (typeEncoding == NULL) { + size_t keyLength; + char *name; + + if ((keyLength = [key UTF8StringLength]) < 1) + return [self valueForUndefinedKey: key]; + + if ((name = malloc(keyLength + 3)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: keyLength + 3]; + + memcpy(name, "is", 2); + memcpy(name + 2, [key UTF8String], keyLength); + name[keyLength + 2] = '\0'; + + name[2] = toupper(name[2]); + + selector = sel_registerName(name); + + free(name); + + typeEncoding = [self typeEncodingForSelector: selector]; + + if (typeEncoding == NULL || + *typeEncoding == '@' || *typeEncoding == '#') + return [self valueForUndefinedKey: key]; + } switch (nextType(&typeEncoding)) { case '@': case '#': ret = [self performSelector: selector]; Index: tests/OFObjectTests.m ================================================================== --- tests/OFObjectTests.m +++ tests/OFObjectTests.m @@ -54,11 +54,11 @@ double _doubleValue; } @property (retain) id objectValue; @property Class classValue; -@property bool boolValue; +@property (getter=isBoolValue) bool boolValue; @property char charValue; @property short shortValue; @property int intValue; @property long longValue; @property long long longLongValue; @@ -240,11 +240,11 @@ forKey: @"unsignedLongLongValue"]) && R([m setValue: [OFNumber numberWithFloat: 110] forKey: @"floatValue"]) && R([m setValue: [OFNumber numberWithDouble: 120] forKey: @"doubleValue"]) && - [m boolValue] == 0 && + [m isBoolValue] == 0 && [m charValue] == 10 && [m shortValue] == 20 && [m intValue] == 30 && [m longValue] == 40 && [m longLongValue] == 50 &&