为什么setValue:forKey:在32位系统上失败而不是64位?

Gre*_*own 4 64-bit 32-bit objective-c kvc swift

我最近向Apple提交了一个关于此问题的错误报告,但我想我会问这个问题,以防万一我遗漏了一些明显的东西.在Objective-C中,以下调用在64位系统上正常工作,但在32位系统上抛出NSInvalidArgumentException:

[self setValue:@"true" forKey:@"flag"];
Run Code Online (Sandbox Code Playgroud)

"flag"属性是BOOL:

@property BOOL flag;
Run Code Online (Sandbox Code Playgroud)

此外,调用在Swift/32位中工作正常,其中属性是Bool:

var flag: Bool = false
Run Code Online (Sandbox Code Playgroud)

类似地,此调用在64位系统上在Swift中正常工作,但在32位系统上抛出NSInvalidArgumentException("index"是Int):

setValue("2", forKey: "index")
Run Code Online (Sandbox Code Playgroud)

然而它在Objective-C/32-bit中运行良好,其中属性是NSInteger.

无论语言或处理器架构如何,我都希望这些调用能够正常工作.有没有人对他们为什么不这样做有所了解?

CRD*_*CRD 5

答案就在评论中,如果你把它们全部结合起来......

setValue:forKey:没有需要NSNumber/ NSValue为原始类型的属性,但通常会传递一个.

观察到的发布也不是64位与32位,示例代码也可能在64位系统上失败.

这完全BOOL取决于它的性质,是否是a char或a bool,如评论所暗示的那样 - 这取决于许多事情(来自10.10.5上运行的Xcode 6.4):

/// 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
Run Code Online (Sandbox Code Playgroud)

setValue:forKey在设置<type>的基本类型属性时,- <type>Value对它传递的任何对象进行调用.

如果BOOLchar它调用- charValue,并且NSString没有这样的方法 - 那么失败.

如果BOOLbool电话- boolValue,那就一切都好NSString.

简单修复:

@property bool flag;
Run Code Online (Sandbox Code Playgroud)

而应该到处并有额外的好处是flag始终是真/假,YES/NO,另一254种可能性,1/0,而不是一个char即可.

试想一下,如果C的设计师没有吝啬并且从一开始就实际包含了一个真正的布尔类型,那么会有多么不同的东西......