Singleton and init with parameter

前端 未结 6 1349
孤街浪徒
孤街浪徒 2020-12-24 07:02

I want to use the singleton pattern in my class which has a private init with parameter. It also has a class function called setup which configures

6条回答
  •  天命终不由人
    2020-12-24 07:35

    A simplified version of different answers; but without any force unwraps, not having shared as a func and having the possibility to have a config. It doesn't need to be more complicated then this, which works well with Swift 5:

    import UIKit
    
    final class ParameterSingleton {
    
      static var shared: ParameterSingleton {
        if let initializedShared = _shared {
          return initializedShared
        }
        fatalError("Singleton not yet initialized. Run setup(withConfig:) first")
      }
      private static var _shared: ParameterSingleton? // This can only be set by the setup() func since it is private
      private var config: ParameterSingletonConfig // The configuration for the singleton. Could be a `String` if so requested
    
      /// The ParameterSingleton setup func. Will initialize the singleton with the config. Without a config, `shared` will cause a `fatalError`
      ///
      /// - Parameter config: The config needed for initializing the singleton
      class func setup(withConfig config: ParameterSingletonConfig) {
        _shared = ParameterSingleton(withConfig: config)
      }
    
    
      // Make the init private so this class can only be used be invoking the `setup(withConfig:)` func
      private init(withConfig config: ParameterSingletonConfig) {
        self.config = config
      }
    
      /// The public func to do something
      func doSomething() {
        print("Config URL: \(config.url)")
      }
    }
    
    struct ParameterSingletonConfig {
      let url: String
    }
    
    //Will cause fatalError
    ParameterSingleton.shared.doSomething()
    
    //Will not cause fatalError
    ParameterSingleton.setup(withConfig: ParameterSingletonConfig(url: "http://www.google.com"))
    ParameterSingleton.shared.doSomething()
    

    Of course, if you only need to set one parameter, you could remove ParameterSingletonConfig and replace it with a String instead

提交回复
热议问题