【问题标题】:How to use Swift struct in Objective-C如何在 Objective-C 中使用 Swift 结构
【发布时间】:2014-11-28 04:11:41
【问题描述】:

我有一个存储应用程序常量的结构,如下所示:

struct Constant {

    static let ParseApplicationId = "xxx"
    static let ParseClientKey = "xxx"

    static var AppGreenColor: UIColor {
        return UIColor(hexString: "67B632")
    }
}

这些常量可以在 Swift 代码中使用,例如调用 Constant.ParseClientKey。但在我的代码中,它还包含一些 Objective-C 类。所以我的问题是如何在 Objective-C 代码中使用这些常量?

如果这种声明常量的方式不好,那么创建用于 Swift 和 Objective-C 代码的全局常量的最佳方式是什么?

【问题讨论】:

  • 请遵循常见的 swift 代码风格,并使用小写字母开始您的 let/var 标识符。
  • @NikolaiRuhe 这不是结构静态属性的正确样式吗?很像UIControlEvents.TouchUpInside?
  • @NikolaiRuhe 看看 Swift 声明:developer.apple.com/library/ios/documentation/UIKit/Reference/… — 它绝对是一个结构体。
  • @LukeRogers 这是因为 Swift 2.0 改变了导入 NS_OPTIONS 样式枚举的方式。语义上UIControlEvent 仍然是一个枚举类型。
  • @NikolaiRuhe LukeRogers:Dinh 没有问这个问题,我们大多数观众也没有点击这里阅读。

标签: objective-c swift constants


【解决方案1】:

遗憾的是,您不能将struct 或全局变量暴露给Objective-C。请参阅the documentation,其中部分说明:

在需要 Objective-C 互操作性时使用类

如果您使用需要处理数据的 Objective-C API,或者您需要将数据模型适合在 Objective-C 框架中定义的现有类层次结构中,您可能需要使用类和类继承来建模你的数据。例如,许多 Objective-C 框架都公开了您希望子类化的类。

到目前为止,恕我直言,最好的方法是这样的:

let ParseApplicationId = "xxx"
let ParseClientKey = "xxx"
let AppGreenColor = UIColor(red: 0.2, green: 0.7, blue: 0.3 alpha: 1.0)

@objc class Constant: NSObject {
    private init() {}

    class func parseApplicationId() -> String { return ParseApplicationId }
    class func parseClientKey() -> String { return ParseClientKey }
    class func appGreenColor() -> UIColor { return AppGreenColor }
}

在 Objective-C 中,你可以像这样使用它们:

NSString *appklicationId = [Constant parseApplicationId];
NSString *clientKey = [Constant parseClientKey];
UIColor *greenColor = [Constant appGreenColor];

【讨论】:

  • Swift 也可以访问?
  • @khunshan 是的。可直接访问ParseClientKey,或通过类Constant.clientKey()
  • 应该使用@objc class Constant: NSObject
  • 这可行,但在 Swift 4 中,我还需要将 @objc 放在每个 class func 前面,以便能够从 Objective C 代码中调用它们。
  • @ElectroBuddha 你可以在课堂上做@objcMembers 以将整个课堂展示给Objective-C代码。
【解决方案2】:

为什么不创建一个同时包含struct@objc class 的文件,如下所示:

import UIKit

extension UIColor {
    convenience init(hex: Int) {
        let components = (
            R: CGFloat((hex >> 16) & 0xff) / 255,
            G: CGFloat((hex >> 08) & 0xff) / 255,
            B: CGFloat((hex >> 00) & 0xff) / 255
        )
        self.init(red: components.R, green: components.G, blue: components.B, alpha: 1)
    }
}

extension CGColor {
    class func colorWithHex(hex: Int) -> CGColorRef {
        return UIColor(hex: hex).CGColor
    }
}

struct Constant {
    static let kParseApplicationId = "5678"
    static let kParseClientKey = "1234"
    static var kAppGreenColor: UIColor { return UIColor(hex:0x67B632) }
    static var kTextBlackColor: UIColor { return UIColor(hex:0x000000) }
    static var kSomeBgBlueColor: UIColor { return UIColor(hex:0x0000FF) }
    static var kLineGrayCGColor: CGColor { return CGColor.colorWithHex(0xCCCCCC) }
    static var kLineRedCGColor: CGColor { return CGColor.colorWithHex(0xFF0000) }
}


@objc class Constants: NSObject {
    private override init() {}

    class func parseApplicationId() -> String { return Constant.kParseApplicationId }
    class func parseClientKey() -> String { return Constant.kParseClientKey }
    class func appGreenColor() -> UIColor { return Constant.kAppGreenColor }
    class func textBlackColor() -> UIColor { return Constant.kTextBlackColor }
    class func someBgBlueColor() -> UIColor { return Constant.kSomeBgBlueColor }
    class func lineGrayCGColor() -> CGColor { return Constant.kLineGrayCGColor }
    class func lineRedCGColor() -> CGColor { return Constant.kLineRedCGColor }
}

为了在 Objective-C 文件中使用,当你需要使用常量时添加这个:

#import "ProjectModuleName-Swift.h"

Swift 用法:

self.view.backgroundColor = Constant.kAppGreenColor

Objective-C 用法:

self.view.backgroundColor = [Constants appGreenColor];

通过这种方式,您可以在一个地方更新整个应用程序的颜色、默认文本、Web 服务 URL。

【讨论】:

  • 我并不清楚我们可以滚动你的答案来发现objective-c部分!
【解决方案3】:

如果您想让代码中的其他 Swift 类型仅通过类访问这些常量,您应该将 let 语句设为私有:

private let AppGreenColor = UIColor(red: 0.2, green: 0.7, blue: 0.3 alpha: 1.0)

@objc class Constant {
    class func appGreenColor() -> UIColor { return AppGreenColor }
}

在 Swift 中,你可以像这样使用它们:

UIColor *greenColor = Constant.appGreenColor

由于 let 语句是私有的,以下行现在将不再编译:

UIColor *greenColor = appGreenColor

【讨论】:

    【解决方案4】:

    虽然这可能会迟到或多余,但我可以使用以下代码使其工作:

    @objcMembers class Flags: NSObject {
        static let abcEnabled = false
        static let pqrEnabled = false
        .
        .
        .
    }
    

    显然,要在 objc c 代码中使用,您必须执行 #import "ProjectModuleName-Swift.h"

    【讨论】:

      猜你喜欢
      • 2015-09-08
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      相关资源
      最近更新 更多