3

I have the following class:

class FeedDataManager: URLManagerdelegate {

let TAG: String = "FeedDataManager"

weak var mDelegate: KeyboardViewController?

var mModelManager: ModelManager!
var mURLManager: UrlManager!
var mGetNewsTimer: NSTimer?

var mFeedsArray: Array<News>!

var mManagedObjectContext: NSManagedObjectContext!
var mPersistentStoreCoordinator: NSPersistentStoreCoordinator!
var mManagedObjectModel: NSManagedObjectModel!

class var sharedInstance: FeedDataManager {
    struct Static {
        static var onceToken: dispatch_once_t = 0
        static var instance: FeedDataManager? = nil
    }

    dispatch_once(&Static.onceToken) {
        Static.instance = FeedDataManager()
    }
    return Static.instance!
}

init (aDelegate: KeyboardViewController) {
    self.mDelegate = aDelegate
}
}

The Problem: If you look at the init method you will see that it should receive as a parameter a delegate pointer that I want to store in the singleton, so basically I need to pass this parameter to this line:

Static.instance = FeedDataManager()

But I have no idea how it's done, Does any knows how this can be done?

BTW: I saw this link: Singleton and init with parameter But the singleton creation there is different.

Community
  • 1
  • 1
Emil Adz
  • 40,709
  • 36
  • 140
  • 187
  • You need to add the same parameter to your `sharedInstance` method or you do what the other question does and add a "setup" method. – rmaddy Apr 30 '15 at 15:13
  • The link that I posted does not uses the dispatch_once method. And it's a two stage initialization when you first have to run the setup method and only after get the instance (This is a huge source of bugs). I want to do it in one step. – Emil Adz Apr 30 '15 at 15:13
  • @EmilAdz You answered the comment I deleted. See my new one. – rmaddy Apr 30 '15 at 15:14
  • @rmaddy I don't want to use the setup method like I said. How the parameter can be passed to the sharedInstance method? – Emil Adz Apr 30 '15 at 15:15
  • Add the parameter to the method signature just like you would add a parameter to any method. – rmaddy Apr 30 '15 at 15:16
  • @Rob, thanks a lot for you comments, your first comment and a small discussion here in my company made me understand that my approach is wrong. You can provide those comments as an answer for acceptance. – Emil Adz Apr 30 '15 at 15:29

1 Answers1

10

We can show you how you can add parameter to declaration of singleton, but that's not really a good idea. The entire idea behind a singleton is that it doesn't matter where it is instantiated, you can use it anywhere. What does it mean if you invoked this singleton in two different places in your code, with different parameters? You have a race condition, where the behavior may change depending upon where and how the singleton was first encountered.

Unrelated, but the dispatch_once is redundant. The static variables are already employed with dispatch_once. See discussion at end of http://developer.apple.com/swift/blog/?id=7 (this is primarily geared towards globals, but as they parenthetically point out, it applies to static variables, too). Also, in Swift 1.2, we can now have static class variables, eliminating the need for the struct, too

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • What if you want to take some code from your app, let's say the component dealing with network calls. Said components will most likely use a url coming from a config file (since having to pass the url as a parameter every time is redundant). Now you want to take this component and make a framework with it, to reuse it somewhere else, you will need said url to change for every app, and subclassing it everytime is imo redundant, i don't see a simplest way than using a singleton with parameters (since the component is already a singleton anyway). – thibaut noah Jun 27 '17 at 13:50
  • I'm sympathetic to the intuition, but giving singleton a parameter is a contraction in terms. In your example, do you plan on passing a URL parameter _everywhere_ you reference the singleton? - If you want something singleton-ish, I'd advise moving away from true singleton and instead use a simple `static` that you initialize once (e.g. rather than calling it `shared`, call it `current` and instantiate it once). Or subclass/wrap it. Or make the configuration parameter just a simple property of the class. Or adopt true dependency injection. Tons of ways, but not singleton w parameter. – Rob Jun 27 '17 at 16:05
  • If you invoke a second time, you should get the same instance that was created the first time. That is the whole point of a singleton. – Clive Jefferies Dec 11 '17 at 16:15
  • 1
    @CliveJefferies - Absolutely. My point was merely that the OP's question about adding a parameter to a singleton is a _non sequitur._ I'd personally keep anything that needed to be set as stand-alone properties, and set them accordingly. E.g. if the MOC is set by the app delegate, that you'd do something like `FeedDataManager.shared.mManagedObjectContext = ...` in the app delegate, rather than adding them as parameters to the initialization of the singleton. Or, better, move this MOC stuff out of the app delegate and into the Singleton's `init` method, eliminating this problem entirely. – Rob Dec 11 '17 at 18:12