Search code examples
swiftfunctionstaticlazy-loadinggrand-central-dispatch

Swift function can be called only once


What is the simplest way to write a piece of code that can be executed only once?

I know a way but has a problem.

first, I write a Boolean variable that has negative value but can be set to positive and cannot change after that

 var hasTheFunctionCalled : Bool = false {
   didSet{
       hasTheFunctionCalled = true
   }
} 

and then write the function and the code inside it:

func theFunction(){
   if !hasTheFunctionCalled{
      //do the thing
   }
   hasTheFunctionCalled = true
 } 

but the problem is that the variable can be changed from somewhere else in the scope and this solution doesn't really look so simple and concrete.


Solution

  • A simple solution is to take advantage of lazy variables in the following way:

    // Declare your "once-only" closure like this
    private lazy var myFunction: Void = {
        // Do something once
    }()
    
    ...
    
    // Then to execute it, just call
    _ = myFunction
    

    This ensures that the code inside the myFunction closure is only executed the first time that the program runs _ = myFunction


    Edit: Another approach is to use so called "dispatch once tokens". This comes from Objective-C and was available in Swift until Swift 3. It is still possible to make it work, however you will need to add a little bit of custom code. You can find more information on this post -> dispatch_once after the Swift 3 GCD API changes


    Edit2: Should be _ = myFunction and not _ = myFunction(), as JohnMontgomery pointed out.