有正确的方法来确定NSNumber是从Bool派生使用Swift吗? [英] Is there a correct way to determine that an NSNumber is derived from a Bool using Swift?
问题描述
包含Bool的NSNumber容易与其他可以包装在NSNumber类中的类型混淆:
NSNumber :true).boolValue // true
NSNumber(integer:1).boolValue // true
NSNumber(integer:1)as? Bool // true
NSNumber(bool:true)as? int // 1
NSNumber(bool:true).isEqualToNumber(1)// true
NSNumber(integer:1).isEqualToNumber(true)// true
但是,有关其原始类型的信息会保留,如下所示:
NSNumber(bool:true).objCType.memory == 99 // true
NSNumber(bool:true).dynamicType.className()==__NSCFBoolean // true
NSNumber(bool:true).isEqualToValue(true)|| NSNumber(bool:true).isEqualToValue(false)// true
问题是:方法是最好的(和/或最安全的)方法来确定Bool是否被包裹在NSNumber中而不是其他东西?都同样有效吗?或者,是否有另一个更好的解决方案?
您可以对Objective-C提出同样的问题,
NSNumber
是免费的桥接到 CFNumberRef
,这是另一种说法 NSNumber
对象实际上是 CFNumber
一个(反之亦然)。现在 CFNumberRef
有一个特定类型的布尔值, CFBooleanRef
,当创建布尔 CFNumberRef
aka NSNumber *
...所以你需要做的是检查你的 NSNumber *
是 CFBooleanRef
的实例:
- (BOOL) isBoolNumber:(NSNumber *)num
{
CFTypeID boolID = CFBooleanGetTypeID(); // CFBoolean的类型ID
CFTypeID numID = CFGetTypeID((__ bridge CFTypeRef)(num)); // num的类型ID
return numID == boolID;
}
注意: $ c> NSNumber / CFNumber
从布尔创建的对象实际上是预定义的常量对象;一个用于 YES
,一个用于 NO
。你可能会试图依靠这个来识别。但是,虽然目前似乎是真实的,并显示在 Apple的源代码
$ b b
附录
Swift代码翻译(GoodbyeStackOverflow):
func isBoolNumber(num:NSNumber) - > Bool
{
let boolID = CFBooleanGetTypeID()// CFBoolean的类型ID
let numID = CFGetTypeID(num)// num的类型ID
return numID == boolID
}
An NSNumber containing a Bool is easily confused with other types that can be wrapped in the NSNumber class:
NSNumber(bool:true).boolValue // true
NSNumber(integer: 1).boolValue // true
NSNumber(integer: 1) as? Bool // true
NSNumber(bool:true) as? Int // 1
NSNumber(bool:true).isEqualToNumber(1) // true
NSNumber(integer: 1).isEqualToNumber(true) // true
However, information about its original type is retained, as we can see here:
NSNumber(bool:true).objCType.memory == 99 // true
NSNumber(bool:true).dynamicType.className() == "__NSCFBoolean" // true
NSNumber(bool:true).isEqualToValue(true) || NSNumber(bool:true).isEqualToValue(false) //true
The question is: which of these approaches is the best (and/or safest) approach to determining when a Bool has been wrapped within an NSNumber rather than something else? Are all equally valid? Or, is there another, better solution?
You can ask the same question for Objective-C, and here is an answer in Objective-C - which you can call from, or translate into, Swift.
NSNumber
is toll-free bridged to CFNumberRef
, which is another way of saying an NSNumber
object is in fact a CFNumber
one (and vice-versa). Now CFNumberRef
has a specific type for booleans, CFBooleanRef
, and this is used when creating a boolean CFNumberRef
aka NSNumber *
... So all you need to do is check whether your NSNumber *
is an instance of CFBooleanRef
:
- (BOOL) isBoolNumber:(NSNumber *)num
{
CFTypeID boolID = CFBooleanGetTypeID(); // the type ID of CFBoolean
CFTypeID numID = CFGetTypeID((__bridge CFTypeRef)(num)); // the type ID of num
return numID == boolID;
}
Note: You may notice that NSNumber
/CFNumber
objects created from booleans are actually pre-defined constant objects; one for YES
, one for NO
. You may be tempted to rely on this for identification. However, though is currently appears to be true, and is shown in Apple's source code, to our knowledge it is not documented so should not be relied upon.
HTH
Addendum
Swift code translation (by GoodbyeStackOverflow):
func isBoolNumber(num:NSNumber) -> Bool
{
let boolID = CFBooleanGetTypeID() // the type ID of CFBoolean
let numID = CFGetTypeID(num) // the type ID of num
return numID == boolID
}
这篇关于有正确的方法来确定NSNumber是从Bool派生使用Swift吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!