7

I'm learning Swift and iOS app development and I was wondering in which cases (if there are some) I should use global variables and constants in an iOS app.

Global variables are variables that are defined outside of any function, method, closure, or type context. Local variables are variables that are defined within a function, method, or closure context.

Using global variables usually seems inelegant and not advisable (it is in fact not recommended by most guides and tutorials) and to pass data between view controller I use the prepareForSegue(_: sender:) method.

There are some cases however where it seems to me that the use of globals would make the code simpler and faster.

For example Apple recommends to store a NSDateFormatter or a NSNumberFormatter for each format pattern and not to recreate or to change one every time it is needed. In an app I'm developing to learn the language, most of the view controllers use a NSDateFormatter and a NSNumberFormatter and creating a new one for each view controller might not be a good idea. I could pass it with prepareForSegue, but I thought that maybe in this case it would be better to use a global var holding an instance of the formatter that every view controller could use.

So are there any cases where I should use global variables?

Lorenzo Rossi
  • 613
  • 1
  • 8
  • 18
  • 3
    I don't think so. Even for the example you provide, you could "store" these formatters as properties of a, say, singleton `Settings`. And even calling up the named singleton you could do not via global const, but via static property of the class. – 0x416e746f6e Dec 26 '15 at 22:48
  • Yes, when you want to create a class variable in swift for a class, you need to use a global. Once class variables are supported in swift, there really should be no reason for a global unless you need to improve performance – Knight0fDragon Dec 26 '15 at 23:03
  • 2
    Globals are convenient, but should generally be avoided. Google "globals are evil" and you'll find tons of discussions on why it's bad, alternatives, etc. Unfortunately, this question (a) has been discussed many times here; and (b) is a matter of opinion, anyway, so this question should be closed. – Rob Dec 26 '15 at 23:10
  • @Knight0fDragon doesn't swift's `static var` work as a class variable? – Lorenzo Rossi Dec 27 '15 at 17:34
  • @Lorenzo Rossi, when did they start allowing static vars in classes, and why would they still not support class variables, other than as properties that do not have built in stored data, I swear I do not get the thought processes that are going on. I would say the difference is that class variables are property variables, but it seems the static var can also be a property. Well now that they allow statics in a class, globals are not needed other that for efficiency purposes – Knight0fDragon Dec 27 '15 at 17:44

1 Answers1

10

Every time you find yourself using a global, you need to take a step back and think hard about what the data is and how it relates to the rest of your app. It is easy to say you need to avoid globals, the hard part is knowing the best alternative for the scenario, something even veteran Cocoa developers will disagree on.

In the singleton pattern, you create a class and stash your global inside it. This is often offered as a solution because it's the easiest to prescribe and follow, but many times I wonder if it is a solution at all. Wrapping a class around a global doesn't give you any additional protections. After all, the class itself is now a global entity. I like to think of the Singleton pattern as a way of organizing, categorizing and containing globals as opposed to avoiding globals.

Singletons should be reserved for the tentpoles of your application like database or remote backend connection handlers. Every Cocoa/CocoaTouch App comes with a built in Singleton, the AppDelegate, and in many cases, assorted things can go there.

In many cases, the "correct" solution is to pass the data along, such as passing data between view controllers in the prepareForSegue: class. This is well described in Andy Matuschak's brilliant WWDC 2014 session, Advanced iOS Application Architecture and Patterns. I agree with you though, that this doesn't apply in your example. In your example, you're not handing relevant data between two views, you're trying to share a common facility to conserver resources.

For your specific example, I would use a Singleton or similar pattern. One way that makes sense to me is to stash them inside their corresponding classes using extensions. For example:

extension NSDateFormatter {
  static let newDateFormatter = NSDateFormatter()
}

// use it in your app like this:
NSDateFormatter.newDateFormatter

Like commenters said, this is a matter of opinion. Also keep in mind that Swift is still young and while it borrows heavily from Cocoa out of necessity, idioms are still evolving.

hashemi
  • 2,608
  • 1
  • 25
  • 31
  • I can't understand Cocoa framework seems forcing you to write the entire app in a single class seems like and this is the most stupid thing i ever experienced i simply cannot have my own structs and classes and packages – nikoss Jul 12 '17 at 02:49