4 个版本 (破坏性更新)
0.3.0 | 2022 年 4 月 8 日 |
---|---|
0.2.0 | 2020 年 9 月 11 日 |
0.1.0 | 2020 年 9 月 10 日 |
0.0.0 | 2020 年 9 月 8 日 |
#40 在 macOS 和 iOS API 中
被用于 proxyconfig
480KB
7K SLoC
Fruity
Fruity 是 Rust 对 Apple 库的绑定,由 @NikolaiVazquez 提供。
索引
捐赠
这样做使我能够创建像这样高质量的开源软件。❤️
用法
此库可在 crates.io 上找到,并可以通过将以下内容添加到项目的 Cargo.toml
中用于您的项目
[dependencies.fruity]
version = "0.3.0"
特性标志
每个库或框架的模块都有自己的与同名的 特性标志。
例如,这是启用 foundation
模块的方法
[dependencies.fruity]
version = "0.3.0"
features = ["foundation"]
此特性会传递性地启用 objc
特性/模块。
目标
惯用 Rust
Fruity 让您在 Rust 中使用这些 C 和 Objective-C API 感觉自然。
-
自动引用计数。
Fruity 利用 Rust 的 所有权模型 来为您处理对象引用计数。
NSObject
是一个智能指针,在retain
上调用Clone
,并在release
上调用Drop
。这正是 Rust 的Arc<T>
的工作方式。 -
选项<NSObject>
.在Objective-C中,除非使用
_Nonnull
标记,否则所有对象都是可空的。这通常会导致过于谨慎的检查或对空对象的疏忽。Fruity则相反,默认将所有对象(例如
NSObject
)设置为非空。可以通过用Option<T>
包装来使对象变为可空。为了使FFI安全且易于使用,以下Objective-C和Rust类型是ABI兼容的
-
NSObject * _Nonnull
和NSObject
-
NSObject * _Nullable
和Option<NSObject>
这是因为
NSObject
是一个围绕NonNull<T>
指针的#[repr(transparent)]
包装。 -
-
结果<T, NSError>
.在Objective-C中,方法接收一个指向失败时放置
NSError
的指针。这使得它很容易避免错误处理并假设成功路径,当发生错误时可能导致bug。Fruity相反,返回一个
Result
,这是Rust中处理错误的规范方式。这确保了必须以某种方式识别错误。 -
自然继承。
这些类型中的大多数都是继承自彼此的类。因为Rust中不可能实现真正的继承,所以Fruity使用
Deref
来模拟Objective-C子类化。 -
构建器模式。
例如,
DispatchQueue
具有许多可配置的输入来创建实例。其中许多输入都有标准默认值,所以每次都必须指定它们,这很繁琐。Swift通过在init
中使用默认参数来解决此问题。然而,Rust没有默认函数参数。Fruity使用构建器模式来解决此问题。例如,请参阅
DispatchQueueBuilder
。这减少了创建调度队列的代码量并简化了代码。
零成本
使用Fruity与Objective-C库交互应该具有与直接在Objective-C中编写相同代码相当的运行时成本。
以下内容与此相符:
-
调用对象方法。
方法分派始终是直接的,不需要使用其他使用
objc::msg_send!
宏的包装器的错误检查开销。这也减少了你的程序大小,因为它不会发出本将永远不会调用的恐慌。这个库被精心编写以确保对
objc_msgSend
的调用总是使用正确的对象类型、方法选择器和参数。 -
获取静态类。
像
NSString::class
这样的获取器通过其符号直接检索类。这与通过objc_getClass
调用 Objective-C 运行时相比是瞬间的。 -
从 Rust 字符串字面量创建
NSString
。nsstring!
宏在编译时创建一个NSString
字面量(即@"string"
)。它没有运行时分派/分配/初始化成本。
这个库的某些部分仍然不是零成本的。在此处获得您的帮助将非常感激!
这些是
selector!
宏。有关详细信息,请参阅 问题 #2。
许可
该项目可以以您选择的方式发布在 MIT 许可证 或 Apache 许可证(版本 2.0) 下。