我在从Objective-C访问Swift Singleton时遇到了一些麻烦。
@objc class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
}
无法达到swiftSharedInstance。
答案 0 :(得分:21)
Nicky Goethlis的答案是正确的,但我只是想在Swift中添加另一种名为 One line Singleton" 的单例创建方式,这是我最近遇到的并且它没有使用Struct
:
Singleton.swift
@objc class Singleton: NSObject {
static let _singletonInstance = Singleton()
private override init() {
//This prevents others from using the default '()' initializer for this class.
}
// the sharedInstance class method can be reached from ObjC. (From OP's answer.)
class func sharedInstance() -> Singleton {
return Singleton._singletonInstance
}
// Some testing
func testTheSingleton() -> String {
return "Hello World"
}
}
SomeObjCFile.m
Singleton *singleton = [Singleton sharedInstance];
NSString *testing = [singleton testTheSingleton];
NSLog(@"Testing---> %@",testing);
答案 1 :(得分:7)
目前我有以下解决方案。也许我忽略了一些能让我进入" swiftSharedInstance"直接?
@objc class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
// the sharedInstance class method can be reached from ObjC
class func sharedInstance() -> SingletonTest {
return SingletonTest.swiftSharedInstance
}
// Some testing
func testTheSingleton() -> String {
return "Hello World"
}
}
然后在ObjC中我可以获取sharedInstance类方法(在导入xcode后生成swift头绑定)
SingletonTest *aTest = [SingletonTest sharedInstance];
NSLog(@"Singleton says: %@", [aTest testTheSingleton]);
答案 2 :(得分:4)
Swift 5及以上
final class Singleton: NSObject {
@objc static let shared = Singleton()
@objc var string: String = "Hello World"
private override init() {}
}
用于Objective-C
NSLog("Singleton String = %@", [Singleton shared].string]);
答案 3 :(得分:1)
要使SingletonTest
班的成员可以访问(swiftSharedInstance
是此班级的成员),请在班级上使用@objcMembers
修饰符,或直接添加@objc
修饰符swiftSharedInstance
:
@objc @objcMembers class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
}
或者:
@objc class SingletonTest: NSObject {
// swiftSharedInstance is not accessible from ObjC
@objc class var swiftSharedInstance: SingletonTest {
struct Singleton {
static let instance = SingletonTest()
}
return Singleton.instance
}
}
答案 4 :(得分:0)
你几乎拥有它。要在Obj-C中使用Swift类,您需要使用#import "SingletonTest-Swift.h
@class MySwiftClass
生成的标头或前向声明。
此外,该课程需要继承Obj-C课程,就像您在此处NSObject
或标记为@objc
一样。但是,您不需要同时执行这两项操作,@objc
在选择要公开的内容时可以使用更精细的选项。
Apple在所有这些方面都有一些good documentation,你可以看到两个不同的WWDC sessions关于Obj-C互操作性的主题。
答案 5 :(得分:0)
不要忘记将 sharedInstance
设置为 public
public final class TestSwiftMain: NSObject {
@objc public static let sharedInstance = TestSwiftMain()
private override init() {}
@objc public func test() {
print("testing swift framework")
}
}
在 Objc 中使用它
[[testSwiftMain sharedInstance] test];
答案 6 :(得分:0)
创建 $request->validate()
后,请确保在您的应用目标的 Bridging header
中设置 Objective-C Generated Interface Header Name
。如果值为空,则添加以下值:
Build Settings
您需要将 $(SWIFT_MODULE_NAME)-Swift.h
@objc
添加到您的 property wrapper
:
singleton
然后,在 @objc final class Singleton: NSObject {
@objc static let sharedInstance = Singleton()
@objc func foo() { }
}
Objective-C
中,导入以下内容:
class
最后,在编译项目后,您将能够在您的 // Replace the "App" with your Target name.
#import "App-Swift.h"
singleton
中使用来自 Swift
的 Objective-C
:
class