Nested Functions in Swift. Real experience

Nested Functions in Swift. Real experience

I want to give you a clear understanding of nested functions and share my experience in using nested functions in Swift.

Theoretical Part

Swift Functions can have nested functions inside their bodies. Nested functions must be defined before the body of their master function.

Nested functions are accessible only in their master function. (Only inside runReportFlow you can call getWeekReportBody and getMonthReportBody).

Pitfalls!

Reference cycle and memory leaks knowledge in Swift is very useful here. For example, in the code below, the nested function will have a strong reference on Car object.

Functions are very similar to Closures, but they have differences. One of them is the Capture List. The nested function doesn’t have [weak self] list, and that’s why it is easiest to write buggy code with strong references.

First Part. Strong reference

So let’s look at the first part of the code above. We have 2 cases. The car calls a strong function where self is strongly captured by DispatchQueue closure. As a result, we have that the Factory will be deallocated immediately and after 3 secs Car will call showModel() function and will be deallocated too. And it is a problem. So if we want to delete and deallocate factory and car immediately (without some unexpected functions call for example, like showModel() ), that we need to rewrite it with a custom weak reference like in part 2.

Second Part. Weak reference

In the second part, we need to create a custom weak reference.

weak var _self = self. As a result, we have that the Factory and Car will be deallocated immediately and after 3 secs this code will be called _self?.showModel(), but _self is nil because it has a weak reference to Car object.

Practical Part

I clearly understand how to use nested functions and how to resolve strong reference problems here, but I didn’t understand why it is useful to use. I have 5 years of experience in commercial programming development and I think that nested functions are very niche and useless and you can simply avoid using them. You just need to understand how to use them and which problems they have (because you should easy to work with not your nested functions, that was written by someone else), but it is useless to use them by themselves. As for me, they have huge problems and limitations. The main problems are reusability. It is short-sighted to think that these nested functions will be needed only in this master function. What if tomorrow you will need some nested function in another place? Duplicate or refactor – it is your choice. A secondary problem for me is readability. I think that master function with 3 nested functions has poor readability and maintainability in the future. It looks pretty messy as for me.

Conclusions

  • Nested functions are a function inside a master function
  • Nested functions must be defined before the master body code
  • Without knowledge about weak references, you can easily create unwanted strong references and memory leaks
  • Try to avoid nested functions in most cases. I think that the nested functions can be useful in some cases – but it is hard to imagine these cases and it is better to avoid them at all
  • Nested functions can have duplications and refactoring problems if they will be needed in some other places
  • Nested functions have readability and maintainability problems

References

  1. https://docs.swift.org/swift-book/LanguageGuide/Functions.html
  2. https://stackoverflow.com/questions/32968133/what-is-the-practical-use-of-nested-functions-in-swift
  3. https://stackoverflow.com/questions/26665076/is-self-captured-within-a-nested-function/26669552#26669552
  4. https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html

Photo by Alex Knight on Unsplash