深入研究Swift和Objective-C之间的互操作性

当您开始一个新的iOS项目时,毫无疑问,您应该完全使用Swift编写它。 Swift已经接管了Objective-C多年了。 https://www.tiobe.com/tiobe-index/使用Swift强大的编译器,我们可以更安全,更快速地构建软件。

但是在现实世界中,我们可能会在Objective-C中面临许多过时的代码。 由于Swift / Objective-C具有出色的互操作性,因此我们可以维护包含它们的项目。 有关如何设置它们的信息,请查看https://medium.com/ios-os-x-development/swift-and-objective-c-interoperability-2add8e6d6887。 处理旧的ObjC的最常见策略是在Swift中编写任何新功能,并修改Objective-C文件以使用它们。

空性抬头

Swift是一种全新的语言,尽管它与Objective-C兼容。 Swift为我们介绍了一些基本类型,例如DateDataString。 并且它们可以自动桥接到Objective-C中的对象,即NSDate,NSData,NSString。 但是,由于Swift引入了optional / non-optional ,当Swift代码转换为Objective-C时,事情会有些棘手。 这是一个例子。

我们定义一些Swift函数,并通过添加关键字@objc使它们在Objective-C中可用

  @objc func testString(_ string:String){print(string)} 
@objc func testData(_ data:Data){print(data)} @ objc func testDate(_ date:Date){print(date)}

在Objective-C中,我们会得到。

  -(void)testString:(NSString * _Nonnull)string;-(void)testData:(NSData * _Nonnull)data;-(void)testDate:(NSDate * _Nonnull)date; 

因为在Objective-C中没有可选/非可选 ,所以我们有_Nonnull。 有关Objective-C中的可空性的更多信息,请参阅 Apple的博客 )。

如果我们使用nil调用此函数,则只会收到警告。

如果我们不将nil显式地传递给这些函数(例如下面的代码),我们可能也不会意识到那些警告。

这些函数中传递的对象不能为nil,因为在Swift中将这些函数的参数定义为非可选的,因此Swift运行时将尝试从nil创建对象。 这是非常危险的,结果也令人惊讶。

  [self testString:nil];  //没有崩溃,在Swift中为空字符串。[self testData:nil];  //没有崩溃,在Swift中为空数据。[self testDate:nil];  // 崩溃! 

结论

因此,在Swift中编写将在Objective-C中调用的函数时,请始终考虑可空性的不同。 如果可能,将参数对象设置为可选,而不是非可选。