是否有正确的方法来确定 NSNumber 是使用 Swift 从 Bool 派生的? [英] Is there a correct way to determine that an NSNumber is derived from a Bool using Swift?
问题描述
包含 Bool 的 NSNumber 很容易与可以包装在 NSNumber 类中的其他类型混淆:
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
问题是:这些方法中哪一种是确定何时将 Bool 包装在 NSNumber 中而不是其他东西中的最佳(和/或最安全)方法?都一样有效吗?或者,还有其他更好的解决方案吗?
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?
推荐答案
您可以针对 Objective-C 提出同样的问题,这里是 Objective-C 中的答案 - 您可以从 Swift 调用或翻译成 Swift.
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
是免费桥接到 CFNumberRef
,这是另一种说法,NSNumber
对象实际上是一个 CFNumber
一(反之亦然).现在 CFNumberRef
有一个特定的布尔类型,CFBooleanRef
,这在创建布尔值 CFNumberRef
aka NSNumber *
时使用>... 所以你需要做的就是检查你的 NSNumber *
是否是 CFBooleanRef
的实例:
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;
}
注意: 你可能注意到从布尔值创建的 NSNumber
/CFNumber
对象实际上是预定义的常量对象;一个表示YES
,一个表示NO
.您可能很想依靠它进行识别.然而,虽然目前似乎是正确的,并且显示在 Apple 的源代码,据我们所知,它未记录,因此不应依赖.
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
附录
Swift 代码翻译(由 GoodbyeStackOverflow 提供):
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 是使用 Swift 从 Bool 派生的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!