Неразрешенный идентификатор из #define в импортированном заголовочном файле Objc

у меня есть класс Obj-c "constants.h", который выглядит так:

//  constants.h

#import <Foundation/Foundation.h>

@interface constants : NSObject
#define kLookAhead 3600*24*7*4 //seconds*hours*days*weeks
end

В моем myProduct-Bridge-Header.h у меня есть:

#import "constants.h"

Однако, когда я вызываю kLookAhead в классе Swift, например. как это

let timeInterval = kLookAhead

Я получаю сообщение об ошибке "Использование неразрешенного идентификатора kLookAhead"

Все остальные классы, которые я импортирую в myProduct-Bridging-Header.h, работают нормально, и kLookAhead успешно используется в моих классах objc.

Есть что-то, что я должен знать?


person Sjakelien    schedule 25.11.2017    source источник


Ответы (2)


Только «простые» макросы импортируются из (Objective-)C в Swift, сравните "Взаимодействие с C API" в справочнике "Использование Swift с Cocoa и Objective-C". Например,

#define kSimpleInt 1234
#define kSimpleFloat 12.34
#define kSimpleString "foo"

импортируются в Swift как

public var kSimpleInt: Int32 { get }
public var kSimpleFloat: Double { get }
public var kSimpleString: String { get }

но

#define kLookAhead 3600*24*7*4

не импортируется. Возможное решение — заменить определение макроса статической постоянной переменной:

static const int kLookAhead = 3600*24*7*4;

Примечание. Обратите внимание, что в сутках не обязательно 24 часа, это может быть 23 или 25 часов, если часы переводятся назад или вперед для перехода на летнее время. Как правило, лучше использовать методы DateComponents и Calendar для календарных расчетов вместо фиксированных интервалов времени. Пример:

let now = Date()
let fourWeeksAhead = Calendar.current.date(byAdding: .weekdayOrdinal, value: 4, to: now)
person Martin R    schedule 25.11.2017
comment
Спасибо, я только что заменил #define kLookAhead 3600*24*7*4 на #define kLookAhead 2419200. И спасибо за подсказку DateComponents. - person Sjakelien; 25.11.2017

В Swift простые макросы доступны через заголовочный файл моста. Из документации от Apple:

Там, где вы обычно использовали директиву #define для определения примитивной константы в C и Objective-C, в Swift вместо этого вы используете глобальную константу. Например, определение константы #define FADE_ANIMATION_DURATION 0,35 может быть лучше выражено в Swift с помощью let FADE_ANIMATION_DURATION = 0,35. Поскольку простые макросы, подобные константам, напрямую сопоставляются с глобальными переменными Swift, компилятор автоматически импортирует простые макросы, определенные в исходных файлах C и Objective-C.

Итак, вы правы, предполагая, что ваш макрос должен быть доступен как глобальная константа. Но я предполагаю, что все это умножение мешало компилятору рассматривать макрос как простой.

Я использовал результат в качестве макроса в примере проекта, и это сработало.

#define kLookAhead 2419200 //seconds*hours*days*weeks

let timeInterval = kLookAhead // worked
person Puneet Sharma    schedule 25.11.2017
comment
Спасибо. Мартин Р. победил вас, поэтому, к сожалению, я вознаградил его ответ. - person Sjakelien; 25.11.2017
comment
@Sjakelien: Да, я знаю. Но, я думаю, хорошо, что вы смогли решить свою проблему самостоятельно, прочитав ответ Мартина Р. - person Puneet Sharma; 25.11.2017