Позвоните в Swift Singleton из Objective-C

У меня возникли проблемы с доступом к Swift Singleton из Objective-C.

@objc class SingletonTest: NSObject {

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

swiftSharedInstance не может быть достигнуто.

Ответ 1

На данный момент у меня есть следующее решение. Может быть, я упускаю из виду то, что позволило бы мне напрямую получить доступ к "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

Nicky Goethlis ответ правильный, но я просто хочу добавить еще один способ создания Singleton, называемый Одна строка Singleton" в Swift, с которой я столкнулся недавно, и она не использует 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 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);

Ответ 3

У вас его очень много. Для использования классов Swift в Obj-C вам нужно #import "SingletonTest-Swift.h сгенерировать заголовок или декларацию с помощью @class MySwiftClass.

Кроме того, класс должен наследовать от класса Obj-C, как вы уже здесь, с NSObject или, помеченным @objc, чтобы открыть его. Вам не нужно делать оба, но @objc должен быть более детальным, если вы выбираете вещи для показа.

У Apple есть хорошая документация по всему этому, и есть два разных Сессий WWDC вы также можете посмотреть на тему совместимости Obj-C.

Ответ 4

Чтобы сделать доступными члены класса 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
    }        
}