Swift: доступ к членам структуры C, которые являются объектами - PullRequest
0 голосов
/ 02 марта 2019

Что у меня есть сейчас:

В моем приложении есть глобальная структура 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?


То, что я думал, будет работать:

Это не работает.Свифт утверждает, что MYColors не имеет appBackgroundColor:

let color: CGColor = UnsafePointer<MYColors>(appColors).appBackgroundColor

Я также подумал, может быть, мне просто нужно получить доступ к синглтону, как это:

let color: CGColor = UnsafePointer<MYColors>(MyModuleName.appColors!).appBackgroundColor

Но это тоже не работает.

1 Ответ

0 голосов
/ 04 марта 2019

Объявление 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 импортирует переменные как необязательные, а не (неявно развернутые).

...