在我的应用中,我有一个包含颜色的全局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 Struct的导入版本。我见过很多关于简单结构的帖子,其中包含int
,float
等。
如果我有该结构的全局实例(基本上是单例),appColors
,如何从Swift中访问该结构的成员?
这不起作用。 Swift声称MYColors
没有appBackgroundColor
:
let color: CGColor = UnsafePointer<MYColors>(appColors).appBackgroundColor
我还认为也许我只需要像这样访问单例:
let color: CGColor = UnsafePointer<MYColors>(MyModuleName.appColors!).appBackgroundColor
但这也不起作用。
答案 0 :(得分:1)
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编译器将变量导入为非可选变量,而不是(隐式展开)可选变量。