从Objective-C调用Swift单例

gopyfrb3  于 2023-01-25  发布在  Swift
关注(0)|答案(8)|浏览(227)

我在从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。

iswrvxsc

iswrvxsc1#

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"
  }
}

某个对象文件.m

Singleton *singleton = [Singleton sharedInstance];
NSString *testing = [singleton testTheSingleton];
NSLog(@"Testing---> %@",testing);
0yg35tkg

0yg35tkg2#

Swift 5及以上

final class Singleton: NSObject {

    @objc static let shared = Singleton()

    @objc var string: String = "Hello World"

    private override init() {}   
}

用于Objective-C

#import <ProjectName-Swift.h> // change ProjectName to actual project name 

NSLog("Singleton String = %@", [Singleton shared].string);
5anewei6

5anewei63#

现在我有以下解决方案。也许我忽略了一些可以让我直接访问“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]);
omqzjyyz

omqzjyyz4#

要使SingletonTest类的成员可访问(swiftSharedInstance是此类的成员),请在该类上使用@objcMembers修饰符,或直接在swiftSharedInstance上添加@objc修饰符:

@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
    }        
}
5tmbdcev

5tmbdcev5#

创建Bridging header后,请确保从应用目标在Build Settings中设置Objective-C Generated Interface Header Name。如果该值为空,请添加以下值:

$(SWIFT_MODULE_NAME)-Swift.h

您需要将@objcproperty wrapper添加到您的singleton

@objc final class Singleton: NSObject {

    @objc static let sharedInstance = Singleton()

    @objc func foo() { }
}

然后,在Objective-Cclass中,导入以下内容:

// Replace the "App" with your Target name.
#import "App-Swift.h"

最后,编译完项目后,您将能够在Objective-Cclass中使用来自Swiftsingleton

[[Singleton sharedInstance]foo];
piok6c0g

piok6c0g6#

要在Obj-C中使用Swift类,你需要#import "SingletonTest-Swift.h生成的头文件或者用@class MySwiftClass转发声明。
另外,类需要继承自Obj-C类,就像你在这里用NSObject标记@objc来公开它一样。你不需要同时做这两件事,@objc是在选择要公开的东西时的一个更细粒度的选项。
苹果有一些关于所有这些的好文档,你也可以在Obj-C互操作性的主题上看到两个不同的WWDC sessions

sy5wg1nm

sy5wg1nm7#

不要忘记将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];
5cg8jx4n

5cg8jx4n8#

2022年10月12日更新
所以你不必在每个函数后面都写objC
雨燕级

@objcMembers class SwiftHelpingExtentions: NSObject {

    static let instanceShared = SwiftHelpingExtentions()
        func testingMethod() {     
            print("testing")    
        }
    }
}

C View控件的研究
1.导入:#import "App-Swift.h"
1.调用方法:[SwiftHelpingExtentions.instanceShared testingMethod];

相关问题