为啥 Swift Int 零在 objc 代码中被读取为零?

Posted

技术标签:

【中文标题】为啥 Swift Int 零在 objc 代码中被读取为零?【英文标题】:Why Swift Int zero is read nil in objc code?为什么 Swift Int 零在 objc 代码中被读取为零? 【发布时间】:2019-03-21 10:42:07 【问题描述】:

我正在处理一个混合的 objc 和 swift 项目,我注意到当我在 Swift 类中有一个值为 0 的 Int 属性时,当我从 Objc 代码中读取此值时,它会返回 @987654322 @。

一个具有整数属性的 Swift 类,在 ObjC 中可见:

@objc
class SwiftInt: NSObject 

    @objc let testInt: Int = 0

现在,当我在 Objc 代码中读取此属性时,它说 testIntnil

- (void)viewDidLoad 
    [super viewDidLoad];
    SwiftInt *swiftInt = [SwiftInt new];
    if (swiftInt.testInt == nil) 
        NSLog(@"This shouldn't be nil");
    

如果我设置了除 0 以外的任何其他数字,则该值会正确返回,但对于 0,它会返回 nil。问题是当Int 是原始类型并且它是非可选的时,为什么这个nil 在Objc 中?我正在使用 Swift 4.2。

【问题讨论】:

在 (Objective-)C 中,可以将整数与指针进行比较。 if (swiftInt.testInt == nil) 等价于 if (swiftInt.testInt == 0) – 应该有一个警告 "Comparison between pointer and integer ('int' and 'void *')" 虽然 您是只对nil 感兴趣还是对NULLNilNSNull 感兴趣? ObjC(具有C legacy)根本无法区分nil0(还有NO/falseswiftInt.testInt == NO!swiftInt.testInt 也可以也)。 【参考方案1】:

因为在Objective-C中nil定义为__DARWIN_NULL

#ifndef nil
# if __has_feature(cxx_nullptr)
#   define nil nullptr
# else
#   define nil __DARWIN_NULL
# endif
#endif

在 Obj-C 中定义为(void *)0

所以你的代码:

if (swiftInt.testInt == nil)  ... 
if (0 == nil)  ... 
if (0 == 0)  ... 

这总是正确的

Obj-C http://benford.me/blog/the-macro-behind-nil/ 中关于 nil 的好文章

【讨论】:

以上是关于为啥 Swift Int 零在 objc 代码中被读取为零?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Swift 中的字符串、数组和字典改为值类型

我们可以为返回可选值的 swift 函数添加 @objc 吗?

Xcode/Cocoapods 为啥我不能从 Pod 实现 Swift 协议?

objc 中 id<delegate>这个类型在swift中怎么写

Objc 代码找不到 swift 中定义的 Bool 变量

为啥我的变量值在 Swift 中恢复?