有没有正确的方法来确定NSNumber是使用Swift从Bool派生的?

包含Bool的NSNumber很容易与可以包装在NSNumber类中的其他类型混淆:
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

但是,保留了有关其原始类型的信息,我们可以在此处看到:

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提出相同的问题,这是Objective-C中的答案 – 您可以从Swift调用或转换为Swift.

NSNumber是免费桥接到CFNumberRef,这是另一种说NSNumber对象实际上是CFNumber对象的方式(反之亦然).现在CFNumberRef有一个特定的布尔类型,CFBooleanRef,这在创建一个布尔CFNumberRef即NSNumber *时使用……所以你需要做的就是检查你的NSNumber *是否是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’s source code显示,但据我们所知,它没有记录,因此不应该依赖.

HTH

附录

Swift代码转换(由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
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...