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

时间:2015-08-21 16:39:28

标签: objective-c swift 64-bit 32-bit kvc

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

[self setValue:@"true" forKey:@"flag"];

"标志"属性是BOOL:

@property BOOL flag;

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

var flag: Bool = false

类似地,这个调用在64位系统上的Swift中工作正常但在32位系统上抛出NSInvalidArgumentException("索引"是一个Int):

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

然而它在Objective-C / 32-bit中工作正常,其中属性是NSInteger。

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

2 个答案:

答案 0 :(得分:5)

如果你把它们全部组合在一起,答案就在那里......

setValue:forKey: 要求原始类型属性NSNumber / NSValue,但通常会传递一个。

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

完全取决于BOOL的性质以及它是char还是bool,正如评论所暗示的那样 - 这取决于许多事情(来自Xcode) 6.4在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
设置< type>的基本类型属性时

setValue:forKey在传递的任何对象上调用- <type>Value

如果BOOLchar,则会调用- charValueNSString没有这样的方法 - 所以失败。

如果BOOLbool,则会调用- boolValue,而NSString会调用@property bool flag; ,所以一切都很好。

简单修复:

flag

这应该适用于所有地方并且有额外的奖励,char总是是真/假,是/否,1/0,而不是其他254种可能性之一{ {1}}可以。

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

答案 1 :(得分:1)

如上面@CRD所述,BOOL是32位设备上char的typedef,而NSString没有charValue方法,因此我们可以添加一个简单的NSString类别来修复它,

#import "NSString+DCCharValue.h"

@implementation NSString (DCCharValue)

#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
#else
- (BOOL)charValue {
    return [self boolValue];
}
#endif

@end