是否有正确的方法来确定 NSNumber 是使用 Swift 从 Bool 派生的? [英] Is there a correct way to determine that an NSNumber is derived from a Bool using Swift?

查看:25
本文介绍了是否有正确的方法来确定 NSNumber 是使用 Swift 从 Bool 派生的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

包含 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆