如何在swift中声明一个可以在目标c中使用的常量
如果我将swift常量声明为一个全局常量,如:
let a = "123"
但目标c中找不到a 。
如何解决这个问题?
从Apple Doc:
只要与Objective-C兼容,您就可以访问使用@objc属性标记的类或协议中的任何内容。 这不包括Swift-only特性,例如:
- generics
- 元组
- 枚举在Swift中定义
- 在Swift中定义的结构
- 在Swift中定义的顶层函数
- 全局variables在Swift中定义
- 在Swift中定义的types
- Swift风格的可变参数
- 嵌套types
- 咖喱function
因此不可能访问在Swift中定义的全局variables(常量)或全局函数。
可能的解决scheme:
-
从Apple文档Swift编程语言中 ,可以声明types属性为
class var constant: Int = { return 10 }()
但目前在Swift(beta-3) types属性不支持。
-
你可以声明一个Class函数来得到一个常量值:
在Swift中:
class func myConst() -> String { return "Your constant" }
从Objective-C访问:
NSString *constantValue = [ClassName myConst]; NSLog(@"%@", constaValue);
在Objective-C中使用let
不应该有任何问题,下一个例子是用Xcode 7.2创build的:
MyClass.swift
import Foundation import UIKit @objc class MyClass : NSObject { // <== @objc AND NSObject ARE BOTH NECESSARY!!! let my_color = UIColor( red:128/255,green:32/255,blue:64/255,alpha:1 ) // <== CONSTANT!!! }
MyObjectiveC.m
#import "PROJECTNAME-Swift.h" // <== NECESSARY TO RECOGNIZE SWIFT CLASSES!!! @interface MyObjectiveC () @end @implementation MyObjectiveC @synthesize tableview; // <== ANY UI OBJECT, JUST AS EXAMPLE!!! - (void) viewDidLoad () { MyClass * mc = [ [ MyClass alloc ] init ]; // <== INSTANTIATE SWIFT CLASS!!! tableview.backgroundColor = mc.my_color; // <== USE THE CONSTANT!!! } @end
PROJECTNAME
是您的Xcode项目的名称,如Project Navigator中所示。
(迅速)
public class MyClass: NSObject { public static let myConst = "aConst" }
(然后在ObjC)
[MyClass myConst]
这不正常吗? 正如在这个为我工作。
这也比先创build一个对象( alloc
, init
) 要短一些 。 为每一个常量创造一个新的function是不是很漂亮:/
更新Swift 4
由于Swift 4的Objective-C推理中的变化,您还需要将@objc
注释添加到声明的常量中。 之前的声明变成:
public class MyClass: NSObject { @objc public static let myConst = "aConst" }
ObjC代码保持不变。
在你的课堂上,
let constant: Float = -1 class YourClass: NSObject { class func getMyConstant() -> Float {return constant} ... }
清理,build立让xcode准备这个方法可用于obj-c。 然后在你的obj-c课上
if ([YourClass getMyConstant] != 0) { ... }
首先你需要知道自动生成的Swift头文件的重要性。
从Objective-C转换Swift代码是可以理解的。
这个文件是由Xcode自动生成的( 不要在你的项目中查找它 )。
这个文件的重要性在于使用正确的名称,它可以与您的目标名称匹配,但是,可能不是,它是产品模块名称 。 (在您的项目设置中search“产品模块” )
您需要在要使用Swift类的Objective-C类以及 Swift文件的Swift类名称上导入此文件。
#import <ProductModuleName-Swift.h> @class MySwiftClassName;
我的Swift类应该有前缀@objc并从NSObjectinheritance :
@objc class MySwiftClassName: NSObject { let mySwiftVar = "123" }
然后你可以从Objective-C文件中调用你的Swiftvariables:
MySwiftClassName *mySwiftClassO = [[MySwiftClassName alloc] init]; NSString *myVar = mySwiftClassO.mySwiftVar;
确保在每次更改之后清理并重build项目,以强制重新生成此自动生成的文件。
如果你的Swift头文件是自动生成的,你可以通过点击导入文件名来find它,并检查是否所有你需要的代码被正确转录。
在下面的文章中,你可以find更多关于这个的详细信息。 https://solidgeargroup.com/bridging-swift-objective-c