c - Swift:访问作为对象的 C 结构成员
问题描述
我现在拥有的:
在我的应用程序中,我有一个包含颜色的全局 C 结构:
//Colors.h
extern struct MYColors *appColors;
struct MYColors
{
CGColorRef appBackgroundColor;
// ...Lots more colors follow
};
以及匹配的实现文件:
//Colors.m
struct MYColors *appColors = calloc(1, sizeof(struct MYColors));
appColors->appBackgroundColor = CGColorCreateGenericRGB(23.0f/255.0f, 24.0f/255.0f, 26.0f/255.0f, 1.0f);
这使我可以集中所有应用程序的颜色。在各种自定义视图中,我在 Objective-C 中编写如下代码:
- (void) updateLayer {
someCGLayer.backgroundColor = appColors->appBackgroundColor;
}
我需要的:
我开始将此应用程序迁移到 Swift,但我无法弄清楚如何访问此 C 结构的导入版本。我看过很多关于包含 , 等的简单结构的int
帖子float
。
如果我有这个结构的全局实例(基本上是单例),appColors
我如何从 Swift 访问该结构的成员?
我认为会起作用的:
这不起作用。斯威夫特声称MYColors
没有appBackgroundColor
:
let color: CGColor = UnsafePointer<MYColors>(appColors).appBackgroundColor
我还想也许我只需要像这样访问单例:
let color: CGColor = UnsafePointer<MYColors>(MyModuleName.appColors!).appBackgroundColor
但这也不起作用。
解决方案
C 声明
extern struct MYColors * appColors;
被导入到 Swift 作为
public var appColors: UnsafeMutablePointer<MYColors>!
在 Swift 中解引用指针是通过pointee
属性完成的,因此 Swift 等效于 (Objective-)C 代码
appColors->appBackgroundColor
是
appColors.pointee.appBackgroundColor
该值的类型是Unmanaged<CGColor>!
因为 Swift 编译器不知道应该如何管理对象的内存。在您的情况下,调用者不负责释放对象,因此最终代码是:
let bgColor = appColors.pointee.appBackgroundColor.takeUnretainedValue()
有关非托管引用的更多信息,请参阅Unmanaged
。
备注:如果appColors
所有结构成员在访问时都保证为非NULL,那么您可以_Nonnull
在接口中对它们进行注释:
struct MYColors {
CGColorRef _Nonnull appBackgroundColor;
// ...
};
extern struct MYColors * _Nonnull appColors;
然后,Swift 编译器将变量导入为非可选变量,而不是(隐式展开的)可选变量。
推荐阅读
- python - Python QThread 与主程序的通信
- flutter - 在 DART 中调用操作后如何更新我的页面?
- xml - XPath 仅在任何其他元素之前获取第一个子注释
- react-native - 必须在 Android 应用清单中定义 expo_runtime_version 或 expo_sdk_version 之一
- arm - 障碍 - 如何确保对寄存器的写操作已完成?
- c++ - C++ 编译器 - 运行 ARM SQ2 芯片的 Microsoft Surface Pro X
- c# - 在 MVC 中使用双重值
- regex - 如何按照自定义模式从变量获取所有字符串实例到bash中的数组?
- r - 获取 c++ 异常尝试使用 rvest 和 V8 抓取 javascript 呈现的网页
- css - 我如何内联显示 React 组件