Index: src/OFKeyValueCoding.h ================================================================== --- src/OFKeyValueCoding.h +++ src/OFKeyValueCoding.h @@ -66,8 +66,18 @@ * @param value The value for the specified undefined key * @param key The undefined key of the value to set */ - (void)setValue: (nullable id)value forUndefinedKey: (OFString*)key; + +/*! + * @brief This is called by @ref setValue:forKey: if the specified key is a + * scalar, but the value specified is `nil`. + * + * By default, this throws an @ref OFInvalidArgumentException. + * + * @param key The key for which the value `nil` was specified + */ +- (void)setNilValueForKey: (OFString*)key; @end OF_ASSUME_NONNULL_END Index: src/OFObject+KeyValueCoding.m ================================================================== --- src/OFObject+KeyValueCoding.m +++ src/OFObject+KeyValueCoding.m @@ -22,10 +22,11 @@ #import "OFObject.h" #import "OFObject+KeyValueCoding.h" #import "OFString.h" #import "OFNumber.h" +#import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFUndefinedKeyException.h" int _OFObject_KeyValueCoding_reference; @@ -137,10 +138,15 @@ if (*typeEncoding != 0) { [self setValue: value forUndefinedKey: key]; return; } + + if (valueType != '@' && valueType != '#' && value == nil) { + [self setNilValueForKey: key]; + return; + } switch (valueType) { case '@': case '#': { @@ -184,6 +190,11 @@ { @throw [OFUndefinedKeyException exceptionWithObject: self key: key value: value]; } + +- (void)setNilValueForKey: (OFString*)key +{ + @throw [OFInvalidArgumentException exception]; +} @end Index: tests/OFObjectTests.m ================================================================== --- tests/OFObjectTests.m +++ tests/OFObjectTests.m @@ -18,10 +18,11 @@ #import "OFString.h" #import "OFNumber.h" #import "OFAutoreleasePool.h" +#import "OFInvalidArgumentException.h" #import "OFMemoryNotPartOfObjectException.h" #import "OFOutOfMemoryException.h" #import "OFUndefinedKeyException.h" #import "TestsAppDelegate.h" @@ -252,9 +253,13 @@ [m unsignedIntValue] == 80 && [m unsignedLongValue] == 90 && [m unsignedLongLongValue] == 100 && [m floatValue] == 110 && [m doubleValue] == 120) + + EXPECT_EXCEPTION(@"Catch -[setValue:forKey:] with nil key for scalar", + OFInvalidArgumentException, [m setValue: nil + forKey: @"intValue"]) [pool drain]; } @end