Why does setValue: forKey: crash on a 32-bit system, but not 64-bit?

I recently posted an Apple bug report, but I thought I would always ask a question if I have something missing. 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 BOOL:

 @property BOOL flag; 

Next, the call works fine in Swift / 32-bit, where the property is Bool:

 var flag: Bool = false 

Similarly, this call works fine in Swift on a 64-bit system, but throws an NSInvalidArgumentException on a 32-bit system ("index" is Int):

 setValue("2", forKey: "index") 

However, it works fine in Objective-C / 32-bit, where the property is NSInteger.

I would expect these calls to work correctly regardless of the language or processor architecture. Can anyone understand why they cannot?

+4
source share
1 answer

The answer is in the comments if you combine them all ...

setValue:forKey: does not require NSNumber / NSValue for primitively typed properties, but you usually pass one.

The observed release does not boil down to 64-bit and 32-bit, either, the sample code may fail on 64-bit systems.

It all depends on the nature of BOOL and whether it is char or BOOL , as the comment suggests, and it depends on a number of factors (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 <type> calls - <type>Value for any object that it passed.

If BOOL is char , it calls - charValue , and NSString does not have such a method - so it failed.

If BOOL is BOOL , it calls - boolValue , and NSString has it so that all is well.

Simple fix:

 @property bool flag; 

and this 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 about how different things would be if C designers didn't skimp and actually include the true Boolean type from the start ...

+4
source

All Articles