Swift 3 nested functions vs closures - swift

I have a large method that does some loading and calculating so it shows an activity indicator view to inform the users they should wait. The logic is pretty complex so there are 4 places in which the data processing might break or return (everything is done on closures). Anyway, I didn't want to repeat this code:
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
in 4 places so I figured that I would write a nested function:
func removeActivityView() {
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
}
but then I realised that in Swift I could also do:
let removeActivityView = {
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
}
which is used exactly in the same way and does exactly the same from the user's point of view.
So what is the actual difference between one approach and the other?

They are the same in this case. In Swift:
Nested functions are closures that have a name and can capture values from their enclosing function.
Source
In fact, you could also do:
func foo() {
print("Foo!")
}
let bar = foo
Now foo() and bar() would yield the same result. This can be done for any function that takes in no arguments.
I'm not sure how/if the compiler differentiates these two. If anyone has more information with respect to that, I would be very interested!

Related

Using an instance in a function

I’m new to Swift so I’ve been using the Swift Playgrounds app. On level 2 “Two Experts”, I initialized two experts:
let expert1 = Expert()
let expert2 = Expert()
What I wanted to do was create a function and pass whichever instance into it, access it’s methods etc, something like:
func actions(who: Item, distance: Int, turn: String) {
for 0 to distance {
who.moveforward()
}
ff turn == “Left” {
who.turnleft()
} else if turn == “Right” {
who.turnright()
}
}
Where who is expert1 or expert2.
I couldn’t find a way of doing this so had to write the same actions twice:
Func actions(who: String, distance: Int, turn:String) {
if who == “expert1” {
for 0 to distance {
expert1.moveforward()
} Etc
if who == “expert2” {
for 0 to distance {
expert2.moveforward()
} Etc
Is there a way of passing an instance into a function then perform certain actions if it’s of a particular class?
Since your experts is of type Expert, then the who parameter in your actions method should be of type Expert, if I understand the code correctly. Then you don't need two functions for each of the Experts. Let me know if I understood you correctly, and if it worked out.
Update
#Alexander mentioned that you can also have these methods in an extension on Expert, like so:
extension Expert {
func actions(distance: Int, turn: String) {
// Add method code here
}
}
When adding the method in an extension, every Expert object can use the method. So you could write expert1.actions(1, "Left") or something like that. Here's a link to the official Swift Programming Language guide about extensions.

Difference using deinit and defer for resource deallocation in Swift

I'm learning more about Swift and came across the defer statement recently, which seems really intriguing to me. However I don't really understand it's purpose. Coming from C++ I would have implemented the same functionality using deallocation function and as a matter of fact, as Swift is ARC, it can do the same.
Let's say FooData and BarData both work with data that needs to deallocated.
class FooData {
deinit {
print("FooData being deallocated")
}
}
class BarData {
}
func baz() -> Int {
var a = FooData()
var b = BarData()
defer { print("BarData being deallocated") }
/* sensitive operations that could throw at any time */
return 0
}
baz()
// BarData being deallocated
// FooData being deallocated
So what's the advantage of the defer approach over the deinit approach? Just thinking about using defer for anything besides resource cleanup makes my head hurt...
You are seeing as different but there are not, defer was introduced by Apple as a safe and easy way to handle the clean up before returning, but defer only works for scopes. So let me explain better, if you have some scope defined inside a function an the variable you have created exist only inside the scope you cannot access from the deinit, for example:
func resizeImage(url: NSURL) -> UIImage? {
// ...
let dataSize: Int = ...
let destData = UnsafeMutablePointer<UInt8>.alloc(dataSize)
defer {
destData.dealloc(dataSize)
}
var destBuffer = vImage_Buffer(data: destData, ...)
// scale the image from sourceBuffer to destBuffer
var error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, ...)
guard error == kvImageNoError
else { return nil }
// create a CGImage from the destBuffer
guard let destCGImage = vImageCreateCGImageFromBuffer(&destBuffer, &format, ...)
else { return nil }
// ...
}
In this case it doesn't make sense define the variable destData as global and we need to deallocate once we finish of work with it, so defer it's the choice.
I think deinit it can be used for more global scope, for example when you implement the Key-Value Observer using NSNotificationCenter or something else you need.
I hope this help you.
Using defer inside a method means that its work will be executed as the method is exiting.
override func viewDidLoad() {
super.viewDidLoad()
print("Step 1")
myFunc()
print("Step 5")
}
func myFunc() {
print("Step 2")
defer { print("Step 3") }
print("Step 4")
}
"Step 1", "Step 2", "Step 4", "Step 3", "Step 5" – steps 3 and 4 are switched because 3 is deferred until the myFunc() method ends, i.e. when it goes out of scope programmatically.
About deinit, this is used to run code before deinitialization. The deinit code is run automatically. Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself.
class Item {
init() {
print("init called")
}
deinit {
// Called whenever class stops existing.
print("deinit called")
}
}
// Create optional Item variable.
var i: Item? = Item()
// Set optional to nil to force deinit.
i = nil
In programming some functions always appear in pairs. For example, opening a connection and closing that connection, locking a mutex and unlocking a mutex, incrementing a counter, decrementing a counter, allocating memory, deallocating memory.
The pattern usually looks like this:
lock()
... do something ...
unlock()
The middle part can be complicated and long. There can be returns (e.g. for failed preconditions and Swift recommends this pattern with its guard). Sometimes it's very hard not to forget to include that unlock() in all execution paths.
One way to solve the situation nicely is using a helper function:
func doSomething() {
... do something with returns ...
}
lock()
doSomething()
unlock()
but that's not always possible, e.g. when you have several nested objects.
In C the same pattern was often solved with goto:
x = malloc(...);
y = malloc(...);
if (!precondition) {
goto end;
}
... some code ...
end:
free(y);
free(x);
Modern languages came with a better approach which in Swift is implemented using defer (you can also find defer in Go, for example).
lock()
defer {
unlock()
}
... some code ...
This approach has several benefits:
You can have the calls together, which increases readability and makes it very hard to forget the second call.
All returns, precondition checks, error handling will leave the code in correct state because unlock will be always called correctly. This is similar to finally in exception handling in Java (and other languages)
If you are asking about the difference from deinit, it works in a similar way. However defer can work in functions while deinit works only for classes.
Also note that you could reimplement defer using deinit but the usage would be more complicated and the behavior less predictable.
defer could be called conditionally what is impossible to implement with deinit
var i = 1
func foo()->Int {
if i == 1 {
defer {
i = 0
}
}
return i + 1
}
print("foo:", foo(), "i:", i)
Consider a database transaction. You want to close the connection when you're done, but you want to keep the object around to reinstate connections in the future:
stuct foo {
let db = Database()
func useDatabase() throws {
let connection = db.openConnection()
defer {
// close conenction, but keep db around for future use
connection.close
}
try connection.thisCanThrow()
}
}
This is just one example, but there are many like it. In particular, a lot of cases arise where you want to model the restricted lifespan of a state, without binding it tightly to an object's life time.
C++ heavily relies on RAII. Swift is certainly capable of adhering to the same paradigm, but it can also go beyond it with defer.

How do I execute code once and only once in Swift?

The answers I've seen so far (1, 2, 3) recommend using GCD's dispatch_once thus:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
Output:
This is printed only on the first call to test()
This is printed for each call to test()
But wait a minute. token is a variable, so I could easily do this:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
token = 0
test()
Output:
This is printed only on the first call to test()
This is printed for each call to test()
This is printed only on the first call to test()
This is printed for each call to test()
So dispatch_once is of no use if we I can change the value of token! And turning token into a constant is not straightforward as it needs to of type UnsafeMutablePointer<dispatch_once_t>.
So should we give up on dispatch_once in Swift? Is there a safer way to execute code just once?
A man went to the doctor, and said "Doctor, it hurts when I stamp on my foot". The doctor replied, "So stop doing it".
If you deliberately alter your dispatch token, then yes - you'll be able to execute the code twice. But if you work around the logic designed to prevent multiple execution in any way, you'll be able to do it. dispatch_once is still the best method to ensure code is only executed once, as it handles all the (very) complex corner cases around initialisation and race conditions that a simple boolean won't cover.
If you're worried that someone might accidentally reset the token, you can wrap it up in a method and make it as obvious as it can be what the consequences are. Something like the following will scope the token to the method, and prevent anyone from changing it without serious effort:
func willRunOnce() -> () {
struct TokenContainer {
static var token : dispatch_once_t = 0
}
dispatch_once(&TokenContainer.token) {
print("This is printed only on the first call")
}
}
Static properties initialized by a closure are run lazily and at most once, so this prints only once, in spite of being called twice:
/*
run like:
swift once.swift
swift once.swift run
to see both cases
*/
class Once {
static let run: Void = {
print("Behold! \(__FUNCTION__) runs!")
return ()
}()
}
if Process.arguments.indexOf("run") != nil {
let _ = Once.run
let _ = Once.run
print("Called twice, but only printed \"Behold\" once, as desired.")
} else {
print("Note how it's run lazily, so you won't see the \"Behold\" text now.")
}
Example runs:
~/W/WhenDoesStaticDefaultRun> swift once.swift
Note how it's run lazily, so you won't see the "Behold" text now.
~/W/WhenDoesStaticDefaultRun> swift once.swift run
Behold! Once runs!
Called twice, but only printed "Behold" once, as desired.
I think the best approach is to just construct resources lazily as needed. Swift makes this easy.
There are several options. As already mentioned, you can initialize a static property within a type using a closure.
However, the simplest option is to define a global variable (or constant) and initialize it with a closure then reference that variable anywhere the initialization code is required to have happened once:
let resourceInit : Void = {
print("doing once...")
// do something once
}()
Another option is to wrap the type within a function so it reads better when calling. For example:
func doOnce() {
struct Resource {
static var resourceInit : Void = {
print("doing something once...")
}()
}
let _ = Resource.resourceInit
}
You can do variations on this as needed. For example, instead of using the type internal to the function, you can use a private global and internal or public function as needed.
However, I think the best approach is just to determine what resources you need to initialize and create them lazily as global or static properties.
For anyone who stumbles on this thread... We ran into a similar situation at Thumbtack and came up with this: https://www.github.com/thumbtack/Swift-RunOnce. Essentially, it lets you write the following
func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated: Bool)
runOnce {
// One-time code
}
}
I also wrote a blog post explaining how the code works, and explaining why we felt it was worth adding to our codebase.
I found this while searching for something similar: Run code once per app install. The above solutions only work within each app run. If you want to run something once across app launches, do this:
func runOnce() {
if UserDefaults.standard.object(forKey: "run_once_key") == nil {
UserDefaults.standard.set(true, forKey: "run_once_key")
/* run once code */
} else {
/* already ran one time */
}
}
If the app is deleted and re-installed, this will reset.
Use NSUbiquitousKeyValueStore for tracking a value across installs and devices as long as user using same appleID.

What is the practical use of nested functions in swift? [duplicate]

This question already has answers here:
What is the benefit of nesting functions (in general/in Swift)
(3 answers)
Closed 6 years ago.
What is the practical use of nested functions? It only makes the code harder to read and doesn't make a particular case easy.
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
Source
I think the core of your question is: Why not use private function instead of an ugly nested function?
Simply put, nested functions can ease readability and encapsulation.
Similarly one can ask, what's the practical use of local variables (of a function) vs instance variables? To me it's really the same question. Only that nested functions are less common.
Readability
A private function can still be accessed from other functions in your class. The same isn't true for nested functions. You're telling your developers, this only belongs to this function (contrary to private functions where they belong to the entire class). Back off and don't mess with it, if you need similar capability, go write your own!
The moment you see a private function you have to think, which function will call it. Is it the first function or the last? Let me search for it. Yet with a nested function you don't have to look up and down. It's already known which function will call it.
Also if you have 5 private functions, where 3 of them are called in a single public function then by nesting them all under the same public function you're communicating to other developers that these private functions are related.
In short, just as you don't want to pollute your public namespace, you don't want to pollute your private namespace.
Encapsulation
Another convenience is that it can access all the local parameters to its parent function. You no longer need to pass them around. This would eventually mean one less function to test, because you've wrapped one function inside another. Additionally if you're calling that function in a block of the non-nested function, then you don't have to wrap it into self or think about creating leaks. It's because the lifecycle of the nested function is tied to the lifecycle of its containing function.
Another use case would be when you have very similar functions in your class, say like you have:
extractAllHebrewNames() // right to left language
extractAllAmericanNames() // left to right language
extractAllJapaneseNames() // top to bottom language
Now if you have a private func named printName (that prints names), it would work if you switch the case based on language, but what if just you don't/can't do that. Instead you can write your own nested functions (They could all now have the exact same name. because each is in a different namespace.) inside each separate extract function and print the names.
Your question is somewhat similar, to why not use 'if else' instead of a 'Switch case.
I think it's just a convenience provided (for something that can be dealt without using nested functions).
NOTE: A nested function should be written before it's callsite within the function.
Error: use of local variable 'nested' before its declaration
func doSomething(){
nested()
func nested(){
}
}
No Error:
func doSomething(){
func nested(){
}
nested()
}
Similarly a local variable used in a nested function must be declared before the nested function
BE AWARE:
If you're using nested functions, then the compiler won't enforce self checks.
The compiler is not smart enough. It will NOT throw error of:
Call to method 'doZ' in closure requires explicit 'self.' to make capture semantics explicit
This could result in hard to find memory leaks. e.g.
class P {
var name: String
init(name: String) {
print("p was allocated")
self.name = name
}
func weaklyNested() {
weak var _self = self
func doX() {
print("nested:", _self?.name as Any)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
doX()
}
}
func stronglyNested() {
func doZ() {
print("nested:", name)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
doZ() // will NOT throw error of: `Call to method 'doZ' in closure requires explicit 'self.' to make capture semantics explicit`
}
}
deinit {
print("class P was deinitialized")
}
}
class H {
var p: P
init(p: P) {
self.p = p
}
}
var h1: H? = H(p: P(name: "john"))
h1?.p.weaklyNested()
h1 = nil // will deallocate immediately, then print nil after 2 seconds
var h2: H? = H(p: P(name: "john"))
h2?.p.stronglyNested()
h2 = nil // will NOT deallocate immediately, will print "john" after 2 seconds, then deallocates
tl;dr solution:
use weak var _self = self and inside the nested function reference to self with the weak reference.
don't use nested functions at all :( Or don't use instance variables inside your nested functions.
This part was written thanks to this original post from Is self captured within a nested function?
One use case is operations on recursive data structures.
Consider, for instance, this code for searching in binary search trees:
func get(_ key: Key) -> Value? {
func recursiveGet(cur: Node) -> Value? {
if cur.key == key {
return cur.val
} else if key < cur.key {
return cur.left != nil ? recursiveGet(cur: cur.left!) : nil
} else {
return cur.right != nil ? recursiveGet(cur: cur.right!) : nil
}
}
if let root = self.root {
return recursiveGet(cur: root)
} else {
return nil
}
}
Of course, you can transform the recursion into a loop, doing away with the nested function. I find recursive code often clearer than iterative variants, though. (Trade off vs. runtime cost!)
You could also define recursiveGet as (private) member outside of get but that would be bad design (unless recursiveGet is used in multiple methods).
There is the principle (since Objective-C) that "code can be data". You can pass code around, store it in a variable, combine it with other code. This is an extremely powerful tool. Frankly, if I didn't have the ability to treat code as data, most of the code I write would be ten times harder to write, and ten times harder to read.
Functions in Swift are just closures, so nested functions make perfectly sense, since this is how you write a closure when you don't want to use one of the many available shortcuts.
In your example, you can create a variable which is also a function like this:
var myStepFunction = chooseStepFunction(true)
myStepFunction(4)
The benefit of nested function is really nice. For example, let's say you are building an app for the calculator, you can have all your logic in one function, as the following:
func doOperation(operation: String) -> ((Double, Double) -> Double)? {
func plus(s: Double, d: Double) -> Double {
return s + d
}
func min(s: Double, d: Double) -> Double{
return s - d
}
switch operation {
case "+":
return plus
case "-" :
return min
default :
return nil
}
}
var myOperationFunction = doOperation("-")?(4, 4) // 0
var myOperationFunction2 = doOperation("+")?(4, 5) //9
In some cases, you are not allowed to see the implementation of some function, or not responsible for them. Then hidding them inside other function is really a good approach. For instance, assume that you colleague is reaponsible for developing the plus and min functions, he/she will do that, and you just use the outer function.
It is deferent from closure, because in clouser, you pass your logic to other logic, which will call yours. It is kind of plugin. For instance, after calling the http request, you can pass the code that you want your app to do when receiving the response from the server

Refactoring help to reduce duplication

I have several ViewControllers all with several methods like the below (and these are virtually the only methods in the classes.)
#IBAction func witnessNameAction(sender: RoundCornerButton) {
presentTextEntryFromViewController(self, initialText: incidentReport.witnessName, completion: { [unowned self] text in
self.incidentReport.witnessName = text
})
sender.setTapped()
}
#IBAction func witnessDescriptionAction(sender: RoundCornerButton) {
presentTextEntryFromViewController(self, initialText: incidentReport.witnessDescription, completion: { [unowned self] text in
self.incidentReport.witnessDescription = text
})
sender.setTapped()
}
Notice that the only difference between the two methods above is which text variable is being get/set. I'm open to any ideas on how to refactor these methods.
Coming from a Java and reading some of Microsoft's excuses for their suggested approaches on MSDN for C#, there are a few ways I can see this being approached.
If the method will only ever have two parameters, create a method that would allow both:
function witness(paramA, paramB) {
if (paramA != null) {
// Target A
}
if (paramB != null) {
// Target B
}
}
This makes me think "I have object A and need to create a unified concept in object B"
Otherwise, an enumeration or static integers would work too:
function witness(target, param) {
switch (target) {
case TARGET_A:
// Target A
break;
case TARGET_B
// Target B
break;
}
}
Which makes me think "I have an object that has fields that I would like external access to change"
You could even use if statements which would allow you to specify multiple targets:
function witness(targets, param) {
if (targets.contains(TARGET_A) {
// Target A
}
if (targets.contains(TARGET_B) {
// Target B
}
}
Which is the same as above in it's own ways.
And last but not least, you could separate the concept and just give self.incidentReport.whatYouNeed as a target:
function witness(target, param) {
target = param;
}
But to me, this is more so "I have an undefined concept of an object that must be set through validation or pre-op", which may be code smell in it's own way. I don't see a problem with a setIfValid() or prepareForSet() style function in the Java world, but that's an entirely different can of worms from my experience. The more I look at it, the more I feel like it all depends on a bunch of other factors that you would have to know as the developer - "Will I ever add more parameters?" "What objects know of what other objects?" "Should I be restricting access anyway?"