1

I have a Swift class which uses a traditional Cocoa singleton pattern: one static shared constant and a private init that is only called once for that shared constant. It's like this:

public class Foo {
    public static let shared = Foo()

    private init() { /* ... */ }

    public func bar() { /* ... */ }
    public func baz() { /* ... */ }
}

// Meanwhile, in multiple places upon multiple threads:

Foo.shared.bar()

Foo.shared.baz()

If I have a dozen threads calling functions on that constant, does it pause all calls until that initializer completes, or should I have some protections within those instance functions to wait for initialization to complete?

jscs
  • 63,694
  • 13
  • 151
  • 195
Ky -
  • 30,724
  • 51
  • 192
  • 308
  • 1
    It is *documented* to be thread safe. See for example https://stackoverflow.com/a/24147830/1187415. – Martin R Jan 14 '19 at 21:58
  • Yes - See https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton – Paulw11 Jan 14 '19 at 21:59
  • @MartinR Those seem to describe how the initializer is safe, but what about the instance functions, like my example `bar` and `baz`? – Ky - Jan 14 '19 at 22:04
  • 1
    To be clear here, it's not `init` that's documented to be thread-safe, it's the assignment to that static property. – jscs Jan 14 '19 at 22:04
  • I've edited to clarify my question isn't solely about the initializer – Ky - Jan 14 '19 at 22:06
  • 2
    Since Swift won't let you call a function until the object is initialised, and the assignment to the static and its associated initialisation is guaranteed to occur only once and is thread safe, you know that the function invocations will also be safe. – Paulw11 Jan 14 '19 at 22:09
  • Did you edit because you're not satisfied by the answer at the duplicate, @BenLeggiero? I'm not sure what's missing; you might want to expand or re-emphasize. – jscs Jan 14 '19 at 22:11
  • 4
    Instantiation and access to the singleton, itself, is threadsafe, but that doesn’t mean that `bar` and `baz` are. E.g., if those two methods perform some unsynchronized access to some shared resource, then they won’t be. It depends entirely upon what these two methods do. But they don’t magically become threadsafe because they’re methods of this singleton. – Rob Jan 14 '19 at 22:12
  • @JoshCaswell [The accepted answer at the duplicate](https://stackoverflow.com/a/24147830/3939277) discusses the different reasons for different singleton approaches. When it comes to the approach I'm using and the question I have, all that answer has to say is that it "is thread safe by the definition of `let`". That doesn't get into the function calls, or _why_ it's thread-safe, nor any proof that this claim is true – Ky - Jan 14 '19 at 22:13
  • 1
    @Rob great point! They can be called simultaneously (to each-other or themselves); they don't do anything thread-dangerous. They simply rely on the initializer completing before they run, so they can't run simultaneously to the initializer. – Ky - Jan 14 '19 at 22:14
  • 1
    Does that title accurately reflect your concern? If not, feel free to re-edit. – jscs Jan 14 '19 at 22:19
  • @JoshCaswell Yes thank you; that is an accurate title – Ky - Jan 14 '19 at 22:19
  • 1
    @Paulw11 do you think this might be re-opened? – Ky - Jan 15 '19 at 18:55

0 Answers0