Как использовать определение Objective-C # из Swift

#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 s

4. 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 {

}