At a Glance
- Swift and Objective-C interaction
- Error Handling
- Empty of the mark
- Lightweight Generics
-
Kindof
Types of - to sum up
Swift and Objective-C interaction
When Swift methods exposed to the Objective-C?
NSObject base class
- Access method control is not
private
level
class MyController : UIViewController {
private func refresh() {
// ...
}
}
- Swift did not use characteristics
class MyController : UIViewController {
func refresh() -> (Int, String)? {
// ...
return (status, response)
}
}
Non NSObject base class
- In complying NSObjectProtocol agreement marked @objc
class MyController : UIWebViewDelegate {
func webViewDidStartLoad(v: UIWebView) {
// ...
}
}
However, when this happens, Xcode will give a warning.
Explicitly marked
- Mark @IBOutlet, @IBAction, @NSManaged and other property to support the Interface Builder, Core Data
class MyController : UIViewController {
@IBAction private func refresh() {
// ...
}
}
- Tag
dynamic
modifier to support Runtime Objective-C, showing the current value may be updated at runtime KVO
class MyController : UIViewController {
dynamic private var title: String? {
get { /* ... */ }
set { /* ... */ }
}
}
- Tag
@objc
modifiers, directly exposed to the Objective-C
class MyController : UIViewController {
@objc private func refresh() {
// ...
}
}
Mark @objc
, the properties will not be able to use Swift
Selector conflict
The Objective-C method name discrimination method, rather than a signature method.
So, the same name as the methods defined in Swift if need be exposed to Objective-C, it is possible to encounter an error message.
For this problem, there are two solutions:
- Use
@objc
attribute exposed to Objective-C method rename
- Using the
@nonobjc
property, a method is prohibited exposed to Objective-C
Function pointer
It is used as a callback function pointer in the C language. However, the C language function pointer can not capture state.
self here is not captured in the function pointer in the C language, so they need another place to store the self, for later use.
Apple introduced @convention (c) property in the Swift 2.0 to solve this problem.
Error Handling
常见的 Objective-C 错误处理方式 和 Swift 异常。
返回类型的差别
Objective-C 中的 id
被翻译为 Swift 中的 AnyObject
Objective-C 中的 BOOL
被翻译为 Swift 中的 Void
闭包的使用
Objective-C 中的 NSError *
被翻译为 Swift 中的 NSError?
在 Objective-C 中处理 Swift 方法抛出的错误
定义以下方法和错误类型:
在 Objective-C 中调用:
在编译时,Swift 会定义 Objective-C 需要使用的部分:
处理Cocoa中的错误
感谢苹果工程师的辛勤付出,Cocoa中的很多错误类型在Swift中已经可用。
已在Swift中可用的比较常见的Cocoa错误类型:
NSCocoaError
NSURLError
AVError
CKErrorCode
CLError
GKErrorCode
HMErrorCode
POSIXError
WKErrorCode
WatchKitErrorCode
为空性标注
请观察 UIView 在 Objective-C 中的定义:
当被转换为 Swift 1.0 的代码时,结果如下:
在转换的过程中,有很多信息是丢失了的。比如:哪些变量可以为nil
?
庆幸的是,Swift 1.1 中便解决了这个问题。
原来,苹果在 Objective-C 中引入了 nullable
, nonnull
, null_unspecified
等修饰符来解决以上问题
标明 Objective-C/C 指针是否可以为nil
,可以:
- 更好地表达 API 的意图
- 改善编译器的静态检查
- 提高 API 在 Swift 中的易用性
很快,在苹果的 SDK 中遍布了这些修饰符。
编译器可以抛出相关的警告,便于开发者及时发现这些问题。
更新后的 SDK 代码:
可以发现,苹果使用 NS_ASSUME_NONNULL_BEGIN
和 NS_ASSUME_NONNULL_END
,假设标记区域为 nonnull
。
审计区域对一些指针做出了假设:
- 单个层级的指针被假设为
nonnull
- NSError** 每个指针层级都是
nullable
然后对 nullable
和 null_unspecified
的情况进行单独标记
C 指针
- 以双下划线为前缀的为空性修饰符可以随处使用
- 为空性修饰符放在指针符号后
这里有一个细节值得注意:
外层指针为 __nullable
,*values 可以为 null。如果 numValues 为0, 你就可以传入 null。
内层指针为 __nonnull
,**values 不可以为 null。你必须传入一个非 null 的数组,用于创建 CFArray。
最后,为空性修饰符已经遍布苹果的 SDK ,建议你也使用它们来改善你的 Objective-C API。
轻量级泛型
以下 Objective-C 中的数组没有标明元素类型,对应的 Swift 代码也没有标明元素类型。
如果使用带有类型的集合,可以
- 提高 API 的表达力
- 使集合更易用
- 改善编译器的静态检查
使用方法:
- 在 < > 中指定参数类型
- 参数类型可以在这个类中尽情使用
在 Categories 和 Extensions 中也可以使用
这个特性支持向后兼容:
- 不需要改变运行时
- 对代码生成无任何影响
如果你不需要类型时,也可以很容易地去除它。
Kindof 类型
来观察一个问题:
编译器并不知道 view.subviews[0] 是一个 Button。
id
是很弱的API协议
以上代码可以将 NSApp
定义为 id
类型。
以上代码可以将 NSApp
定义为 __kindof UIApplication *
类型。
使用__kindof
可以很方便地转换父类和子类。
还可以允许向子类发送消息
__kindof
其实是更实用的id
类型
什么时候在API中使用 id
多数惯用情况下,id
可以被更准确的类型替代:
- 返回
self
的方法可以使用instancetype
- 多数集合使用场景可以对元素类型进行约束
-
__kindof X *
It can be used to express a subclass of class X - For compliance SomeProtocol protocol type, use id <SomeProtocol>
You only need to indicate when to use any type of object id
. such as:
to sum up
Swift and Objective-C co-evolved to better collaborate
- Xcode allows you to switch between these two languages at ease in
Let your Objective-C code with the times
- Objective-C can enhance the expressive power of the new features of the API
- With a stronger type of security check, you can quickly discover the problem
- Let your Objective-C code in a more elegant interface Swift
References:
Swift in Objective-C and Interoperability
Reproduced, please indicate the source , thank you ~
Reproduced in: https: //www.jianshu.com/p/70cbad6eee3a