I recently submitted a bug report to Apple about this, but I thought I would ask the question anyways in case I'm missing something obvious. In Objective-C, the following call works fine on a 64-bit system but throws an NSInvalidArgumentException on a 32-bit system:
[self setValue:@"true" forKey:@"flag"];
The "flag" property is a BOOL:
@property BOOL flag;
Further, the call works fine in Swift/32-bit, where the property is a Bool:
var flag: Bool = false
Similarly, this call works fine in Swift on a 64-bit system but throws NSInvalidArgumentException on the 32-bit system ("index" is an Int):
setValue("2", forKey: "index")
Yet it works fine in Objective-C/32-bit, where the property is an NSInteger.
I would have expected these calls to work correctly regardless of language or processor architecture. Does anyone have any insight into why they might not?
The answer is there in the comments if you combine them all...
setValue:forKey:
does not require an NSNumber
/NSValue
for primitive-typed properties, but you would normally pass one.
The observed issued is not down to 64-bit vs. 32-bit either, the example code can fail on 64-bit systems as well.
It is all down to the nature of BOOL
and whether it is a char
or a bool
,as a comment suggests - and that depends on a number of things (from Xcode 6.4 running on 10.10.5):
/// Type to represent a boolean value.
#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
typedef bool BOOL;
#else
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif
setValue:forKey
when setting a primitive typed property of <type> calls - <type>Value
on whatever object it is passed.
If BOOL
is a char
it calls - charValue
, and NSString
has no such method - so fail.
If BOOL
is bool
it calls - boolValue
, and NSString
has that so all is good.
Simple fix:
@property bool flag;
and that should work everywhere and have the added bonus that flag
will always be true/false, YES/NO, 1/0 and not one of the other 254 possibilities that char
can be.
Just think how different things would be if the designers of C didn't skimp and actually included a real boolean type from the start...