如何使用Swift中的Objective-C #define


71

我正在迁移UIViewController课程,以便对Swift进行一些培训。我通过桥接头成功地使用了Objective-C代码,但是我需要导入一个包含#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源文件中定义的简单宏。

因此,似乎有可能。我已经将包含常量的文件导入到桥接头文件中,但是我的.swift文件没有可见性,无法解决。

我应该怎么做才能使我的常量对Swift可见?

更新:

似乎可以使用NSString常量,但不能使用布尔值:

#define kSTRING_CONSTANT @"a_string_constant" // resolved from swift
#define kBOOL_CONSTANT YES // unresolved from swift

1
尝试使用true而不是YES。
David Berry 2014年

Answers:


61

目前,有些#define已转换,有些未转换。进一步来说:

#define A 1

...成为:

var A: CInt { get }

要么:

#define B @"b"

...成为:

var B: String { get }

遗憾的是,YESNO没有识别和转换由斯威夫特编译器的飞行。

我建议您将#defines转换为实际常数,#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

快点。但不如实际常数。


我可以知道您使用NSString的原因!而不是字符串!?
Ricky 2014年

1
我认为这是因为您不必在使用常量之前测试常量是否为零,因此在使用时将其拆包是“安全的”。但是我不得不让NSString的,但我不是舒适与此时迅速:)
foOg

我猜#defines和consts成为常数:ie lets
Tim


如果我们将其更改为let声明,那么如何通过命令行上的-DCONSTANT = val或xcode plist构建设置传入常量。确实错过了他们的全部要点。
Shayne

22

只是从上面的一些事情快速澄清。

Swift常量使用关键字表示let

例如:

let kStringConstant:String = "a_string_constant"

另外,只有在协议定义中,才能使用{ get },例如:

protocol MyExampleProtocol {
    var B:String { get }
}

8

快速地,您可以在任何类或函数之外声明一个枚举,变量或函数,并且该类将在您的所有类中(全局)可用(无需导入特定文件)。

  import Foundation
  import MapKit

 let kStringConstant:String = "monitoredRegions"

  class UserLocationData : NSObject {    
class func getAllMonitoredRegions()->[String]{
     defaults.dictionaryForKey(kStringConstant)
 }

1
您是否认为有必要清除kStringConstant可以通过提供的内容推断出的类型吗"monitoredRegins"
大都会

不,不是。它只是一种编码实践,我喜欢将任何硬编码的字符串放在首位。以后可以轻松地将其移到常量文件中。
Ankish Jain


0

宏的替代方案可以是全局变量。我们可以在类外部声明全局变量,而无需使用类就可以访问它们。请在下面找到示例

import Foundation
let BASE_URL = "www.google.com"

class test {

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.