[28] 30 天从 Swift 学会 Objective-C:Swift friendly 的 API Swift name

在 Objective-C 与 Swift 的命名有明显的区别,虽然 Swift interface 可以将 Objective-C 的 API 以一定程度的方式改写为 Swift 命名方式。

Photo by @jontyson on Unsplash

可以改写的部分

Objective-C 的 Foundation/Foundtion.h 提供了 NS_SWIFT_NAME 作为改写 API 的关键字:

// Objective-C
NS_SWIFT_NAME(Sandwich.Preferences)
@interface SandwichPreferences : NSObject

@property BOOL includesCrust NS_SWIFT_NAME(isCrusty);

@end

@interface Sandwich : NSObject
@end

范例来自 Apple Developer Documentation [注 1]

其相对应的 Swift interface 则是

一些限制

Swift interface 并不是万能的,在提供方便的 NS_SWIFT_NAME 的同时,有几个要避免的事情:

  1. Namespace 的使用只有 1 个,如Sandwich.Preferences.Detail 是不能使用的
// Objective-C
NS_SWIFT_NAME(Sandwich.Preferences.Detail) // 'swift_name' attribute has invalid identifier for base name
@interface SandwichPreferencesDetail : NSObject
@end

正确使用的方式是 NS_SWIFT_NAME(SandwichPreferences.Detail)

  1. 参数的顺序是不可以更改的。

[进阶] NS_REFINED_FOR_SWIFT 隐藏 API

之前说到在 public header 的实作是会自动出现在 Swift interface 的,但是当我们想要透过改写 API 的顺序或是不想让 Swift client 使用不方便的 API (如: ObjcBool 与 Swift.Bool),我们可以使用 NS_REFINED_FOR_SWIFT 的关键字来处理。

// Objective-C
@interface Color : NSObject
 
- (void)getRed:(nullable CGFloat *)red
         green:(nullable CGFloat *)green
          blue:(nullable CGFloat *)blue
         alpha:(nullable CGFloat *)alpha NS_REFINED_FOR_SWIFT;
 
@end

范例来自 Apple Developer Documentation [注 2]

// Swift
extension Color {
    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var r: CGFloat = 0.0
        var g: CGFloat = 0.0
        var b: CGFloat = 0.0
        var a: CGFloat = 0.0
        __getRed(red: &r, green: &g, blue: &b, alpha: &a)
        return (red: r, green: g, blue: b, alpha: a)
    }
}

请注意的是 __getRed 是不存在於 Swift interface 的。

注记

  1. Renaming Objective-C APIs for Swift - Apple Developer Documentation
  2. Improving Objective-C API Declarations for Swift - Apple Developer Documentation

简单测验

  1. Swift 官方有所谓的 API 编写规范,请问在哪里可以找到?
  2. [进阶] Swift interface 透过哪些机制将 Objective-C API 自动转译为 Swift API

<<:  VSCode 注解就是你的文件

>>:  ## Day28 LineBot models小介绍

Day.26 「闭包要谨慎使用!」 —— JavaScript 闭包(Closure)

我们前面已经认识了函式作用域,也了解了回调函式,但有时候会产生意想不到的事情,造成内存问题,其中一...

Day6. Array & Hash 之间的组合应用

Hash 在其他语言称为Object, Dictionary,但无论是在哪个程序语言中,Hash 和...

CMoney工程师战斗营weekly8

本来以为小验完可以回家的一周结果只是我以为QQ 已经大约3周没回家我,以为目前执行速度还在进度内,殊...

第 04 天 坚持刷题持续进步( leetcode 098 )

https://leetcode.com/problems/validate-binary-sea...

Day 45 (Node.js)

1.版本 https://nodejs.org/en/ 下载LTS (长期稳定版本) 用10以上版本...