#objective-c #macros #swift
#objective-c #макросы #swift
Вопрос:
Я переношу UIViewController
класс, чтобы немного потренироваться с Swift. Я успешно использую код Objective-C через заголовок bridging, но мне необходимо импортировать файл констант, содержащий #define
директивы.
Я видел при использовании Swift с Cocoa и Objective-C (простые макросы) следующее:
Простые макросы
Там, где вы обычно использовали
#define
директиву для определения примитивной константы в C и Objective-C, в Swift вместо этого используется глобальная константа. Например, определение константы#define FADE_ANIMATION_DURATION 0.35
может быть лучше выражено в Swift сlet FADE_ANIMATION_DURATION = 0.35
помощью . Поскольку простые макросы, подобные константам, напрямую сопоставляются с глобальными переменными Swift, компилятор автоматически импортирует простые макросы, определенные в исходных файлах C и Objective-C.
Итак, кажется, это возможно. Я импортировал файл, содержащий мои константы, в заголовок bridging, но у меня нет видимости из моего .swift
файла, не может быть разрешен.
Что я должен сделать, чтобы мои константы были видны Swift?
Обновить:
Кажется, что он работает с NSString
константами, но не с логическими значениями:
#define kSTRING_CONSTANT @"a_string_constant" // resolved from swift
#define kBOOL_CONSTANT YES // unresolved from swift
Комментарии:
1. Попробуйте использовать true вместо YES .
Ответ №1:
На данный момент некоторые #define
s преобразованы, а некоторые нет. Более конкретно:
#define A 1
…становится:
var A: CInt { get }
Или:
#define B @"b"
…становится:
var B: String { get }
К сожалению, YES
и NO
не распознаются и не преобразуются на лету компилятором Swift.
Я предлагаю вам преобразовать ваши #define
s в фактические константы, что в любом случае лучше, чем #define
s.
.h:
extern NSString* const kSTRING_CONSTANT;
extern const BOOL kBOOL_CONSTANT;
.m
NSString* const kSTRING_CONSTANT = @"a_string_constant";
const BOOL kBOOL_CONSTANT = YES;
И тогда Swift увидит:
var kSTRING_CONSTANT: NSString!
var kBOOL_CONSTANT: ObjCBool
Другим вариантом было бы изменить ваши BOOL
определения на
#define kBOOL_CONSTANT 1
Быстрее. Но не так хорошо, как фактические константы.
Комментарии:
1. Могу ли я узнать причину, по которой вы используете NSString! и не строка! ?
2. Я думаю, это потому, что вам никогда не нужно проверять, равна ли константа нулю перед ее использованием, поэтому «безопасно» разворачивать ее при использовании. Однако я бы позволил NSString, но в настоящее время мне не так комфортно со swift 🙂
3. Я полагаю
#define
, что s иconst
s становятся константами: т.е.let
s4. developer.apple.com/library/ios/documentation/Swift/Conceptual/…
5. Как передать константы через -DCONSTANT=val в командной строке или настройках сборки xcode plist, если мы изменим их на объявления let. На самом деле это как бы упускает из виду весь их смысл.
Ответ №2:
Просто краткое разъяснение нескольких вещей из вышеприведенных.
Константы Swift выражаются с помощью ключевого слова let
Например:
let kStringConstant:String = "a_string_constant"
Кроме того, только в определении протокола вы можете использовать { get }
, например:
protocol MyExampleProtocol {
var B:String { get }
}
Ответ №3:
В swift вы можете объявить перечисление, переменную или функцию вне любого класса или функции, и они будут доступны во всех ваших классах (глобально) (без необходимости импортировать конкретный файл).
import Foundation
import MapKit
let kStringConstant:String = "monitoredRegions"
class UserLocationData : NSObject {
class func getAllMonitoredRegions()->[String]{
defaults.dictionaryForKey(kStringConstant)
}
Комментарии:
1. Считаете ли вы, что необходимо определить тип
kStringConstant
, который можно определить по предоставленному контенту,"monitoredRegins"
.2. Нет, не совсем. Это просто практика кодирования, любая жестко закодированная строка, которую я хотел бы поместить сверху. Позже легко переместите его в файл констант.
Ответ №4:
простому языку swift не нужны макросы для всех директив #define. будет разрешено, и сложные макросы должны быть преобразованы в функции
Комментарии:
1. Да, вы правы, используя импортированные макросы C в Swift
Ответ №5:
Альтернативой макросу может быть глобальная переменная . Мы можем объявить глобальную переменную вне класса и получить к ним доступ без использования class . Пожалуйста, найдите пример ниже
import Foundation
let BASE_URL = "www.google.com"
class test {
}