我最近向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。
无论语言或处理器架构如何,我都希望这些调用能够正常工作。有没有人对他们为什么不这样做有所了解?
答案 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
。
如果BOOL
是char
,则会调用- charValue
,NSString
没有这样的方法 - 所以失败。
如果BOOL
为bool
,则会调用- 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