Swift: 访问作为对象的 C 结构成员
Swift: Accessing C Struct Members That Are Objects
我现在拥有的:
在我的应用程序中,我有一个保存颜色的全局 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 访问该结构的成员?
我认为可行的方法:
这不起作用。 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
和所有struct成员访问时保证非NULL那么可以在接口中用_Nonnull
注解:
struct MYColors {
CGColorRef _Nonnull appBackgroundColor;
// ...
};
extern struct MYColors * _Nonnull appColors;
然后 Swift 编译器将变量导入为非可选变量而不是(隐式解包)可选变量。
我现在拥有的:
在我的应用程序中,我有一个保存颜色的全局 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 访问该结构的成员?
我认为可行的方法:
这不起作用。 Swift 声称 MYColors
没有 appBackgroundColor
:
let color: CGColor = UnsafePointer<MYColors>(appColors).appBackgroundColor
我还想也许我只需要像这样访问单例:
let color: CGColor = UnsafePointer<MYColors>(MyModuleName.appColors!).appBackgroundColor
但这也不起作用。
C 声明
extern struct MYColors * appColors;
作为
导入到Swiftpublic 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
和所有struct成员访问时保证非NULL那么可以在接口中用_Nonnull
注解:
struct MYColors {
CGColorRef _Nonnull appBackgroundColor;
// ...
};
extern struct MYColors * _Nonnull appColors;
然后 Swift 编译器将变量导入为非可选变量而不是(隐式解包)可选变量。