Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IIFE in Swift Language

Tags:

swift

iife

In javascript we use IIFEs a lot. Something like

(function() {
    ...do stuff to avoid dirtying scope.
}());

There are closures in Swift, and functions are first class objects. My question is: are there equivalent IIFEs in Swift?

like image 683
Zack Argyle Avatar asked Jun 04 '14 16:06

Zack Argyle


People also ask

What does IIFE stand for?

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

Why do we use IIFE?

IIFEs are very useful because they don't pollute the global object, and they are a simple way to isolate variables declarations. An Immediately-invoked Function Expression (IIFE for friends) is a way to execute functions immediately, as soon as they are created.

Where is IIFE used?

An Immediate-Invoked Function Expression (IIFE) is a function that is executed instantly after it's defined. This pattern has been used to alias global variables, make variables and functions private and to ensure asynchronous code in loops are executed correctly.

What is IIFE pattern?

IIFE (Immediately Invokable Function Expression) is a important concept in JavaScript. it is a commonly used Design Pattern which is used to wrap set of variables and functions which cannot be accessed outside the enclosed scope.


3 Answers

The accepted answer here is misleading—there's an easier and more elegant manner in which to create an immediately-invoked closure expression (IICE).

For all of the details and variances of syntax, see the Apple Swift Documentation for closures. For a simple demo, see this:

let dateString: NSString = { date in
  let timestampFormatter = NSDateFormatter()

  timestampFormatter.dateStyle = .MediumStyle
  timestampFormatter.timeStyle = .MediumStyle

  return timestampFormatter.stringFromDate(date)
}(NSDate())

enter image description here

like image 138
james_womack Avatar answered Oct 01 '22 11:10

james_womack


You can achieve a similar effect using closures, sure:

func iife( f : () -> () ) {
 f()
}

And then say

iffe { 
// my code here
}

If all you truly need is a scope, while Swift does not support the use of {..} as a "scoping operator", you can always do

if 1 == 1 {
// oh, look, a scope :-)
}

as a less fancy way to achieve the same effect. If you're trying to use RAII patterns, you will need to either rely on ARC to cleanup for you, or use a closure though

if true {
    // should also work instead of if 1 == 1
}
like image 25
Enrico Granata Avatar answered Oct 01 '22 11:10

Enrico Granata


Here's another example of a Swift immediately-invoked closure expression (IICE) - which I pronounce as "Icky" (in a nod to JavaScript's IIFE, which is pronounced "Iffy" - http://benalman.com/news/2010/11/immediately-invoked-function-expression/)

var player:AVAudioPlayer = {
        let path = Bundle.main.path(forResource: "sound1", ofType: "mp3")!
        let url = NSURL(fileURLWithPath: path)
        let p = try! AVAudioPlayer(contentsOf: url as URL)
        p.volume = 0.3
        p.prepareToPlay()
        return p
    }()

And if you use the lazy modifier, you are then allowed to access self.

From the Swift Language Guide: "Lazy properties are useful when the initial value for a property is dependent on outside factors whose values are not known until after an instance’s initialization is complete. Lazy properties are also useful when the initial value for a property requires complex or computationally expensive setup that should not be performed unless or until it is needed."

let startVolume:Float = 0.3
lazy var player:AVAudioPlayer = {
       let path = Bundle.main.path(forResource: "sound1", ofType: "mp3")!
       let url = NSURL(fileURLWithPath: path)
       let p = try! AVAudioPlayer(contentsOf: url as URL)
       p.volume = self.startVolume
       p.prepareToPlay()
       return p
  }()

Also see "Setting a Default Property Value with a Closure or Function" in the Swift Language Guide.

like image 35
tonethar Avatar answered Oct 01 '22 10:10

tonethar