从Objective-C调用Swift Singleton

时间:2022-09-07 19:29:55

I'm having some trouble accessing a Swift Singleton from Objective-C.

我在从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 can not be reached.

无法达到swiftSharedInstance。

4 个解决方案

#1


13  

Nicky Goethlis's answer is correct but I just want to add another way of Singleton creation termed as One line Singleton" in Swift which I came across recently and it does not use Struct:

Nicky Goethlis的答案是正确的,但我只是想添加另一种Singleton创建的方式,在Swift中称为One line Singleton,我最近遇到过它不使用Struct:

Singleton.swift

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

SomeObjCFile.m

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

#2


7  

For now I have the following solution. Maybe I am overlooking something that would enable me to access "swiftSharedInstance" directly?

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

}

Then in ObjC I can get the sharedInstance class method (after importing the xcode generated swift header bindings)

然后在ObjC中我可以获取sharedInstance类方法(在导入xcode后生成swift头绑定)

SingletonTest *aTest = [SingletonTest sharedInstance];
NSLog(@"Singleton says: %@", [aTest testTheSingleton]);

#3


0  

You pretty much have it. To use Swift classes in Obj-C you both need to #import "SingletonTest-Swift.h the generated header or forward declaration with @class MySwiftClass.

你几乎拥有它。要在Obj-C中使用Swift类,你需要#import“SingletonTest-Swift.h生成的头文件或使用@class MySwiftClass的前向声明。

Additionally the class needs to inherit from an Obj-C class like you have don here with NSObject or be marked with @objc to expose it. You don't need to do both though, @objc is there to be a more granular option when choosing things to expose.

此外,该类需要继承一个Obj-C类,就像你在这里使用NSObject一样,或者用@objc标记它来暴露它。您不需要同时执行这两项操作,@ objc在选择要公开的内容时会有更细粒度的选项。

Apple has some good documentation on all of this and there are two different WWDC sessions you can watch on the topic of Obj-C interoperability as well.

Apple在所有这些方面都有一些很好的文档,你可以看到两个不同的WWDC会议,主题是Obj-C互操作性。

#4


0  

To make members of the SingletonTest class accessible (swiftSharedInstance is a member of this class), use @objcMembers modifier on the class, or add @objc modifier directly on the swiftSharedInstance:

要使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
    }        
}

Or:

要么:

@objc class SingletonTest: NSObject {

    // swiftSharedInstance is not accessible from ObjC
    @objc class var swiftSharedInstance: SingletonTest {
        struct Singleton {
            static let instance = SingletonTest()
        }
        return Singleton.instance
    }        
}

#1


13  

Nicky Goethlis's answer is correct but I just want to add another way of Singleton creation termed as One line Singleton" in Swift which I came across recently and it does not use Struct:

Nicky Goethlis的答案是正确的,但我只是想添加另一种Singleton创建的方式,在Swift中称为One line Singleton,我最近遇到过它不使用Struct:

Singleton.swift

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

SomeObjCFile.m

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

#2


7  

For now I have the following solution. Maybe I am overlooking something that would enable me to access "swiftSharedInstance" directly?

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

}

Then in ObjC I can get the sharedInstance class method (after importing the xcode generated swift header bindings)

然后在ObjC中我可以获取sharedInstance类方法(在导入xcode后生成swift头绑定)

SingletonTest *aTest = [SingletonTest sharedInstance];
NSLog(@"Singleton says: %@", [aTest testTheSingleton]);

#3


0  

You pretty much have it. To use Swift classes in Obj-C you both need to #import "SingletonTest-Swift.h the generated header or forward declaration with @class MySwiftClass.

你几乎拥有它。要在Obj-C中使用Swift类,你需要#import“SingletonTest-Swift.h生成的头文件或使用@class MySwiftClass的前向声明。

Additionally the class needs to inherit from an Obj-C class like you have don here with NSObject or be marked with @objc to expose it. You don't need to do both though, @objc is there to be a more granular option when choosing things to expose.

此外,该类需要继承一个Obj-C类,就像你在这里使用NSObject一样,或者用@objc标记它来暴露它。您不需要同时执行这两项操作,@ objc在选择要公开的内容时会有更细粒度的选项。

Apple has some good documentation on all of this and there are two different WWDC sessions you can watch on the topic of Obj-C interoperability as well.

Apple在所有这些方面都有一些很好的文档,你可以看到两个不同的WWDC会议,主题是Obj-C互操作性。

#4


0  

To make members of the SingletonTest class accessible (swiftSharedInstance is a member of this class), use @objcMembers modifier on the class, or add @objc modifier directly on the swiftSharedInstance:

要使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
    }        
}

Or:

要么:

@objc class SingletonTest: NSObject {

    // swiftSharedInstance is not accessible from ObjC
    @objc class var swiftSharedInstance: SingletonTest {
        struct Singleton {
            static let instance = SingletonTest()
        }
        return Singleton.instance
    }        
}