self special property inside init(windSpeed:chanceOfRain:) and isDayForWalk() is the current instance of Weather structure. It allows to set and access the structure properties self.windSpeed and self.chanceOfRain.

The structure looks nice.

Nevertheless accessing every time self property may be excessive. The structure initializer and method provide enough context: everything happens inside the structure. Is it possible to get rid of self?

As mentioned in the introduction, Swift encourages you to omit the self keyword whenever possible.

In the previous example, it is recommended to remove self from isDayForWalk() method. This makes the method shorter:

Because isDayForWalk() method is always invoked in the context of Weather's instance, Swift enables access of windSpeed and chanceOfRain without self.

Inside the initializer init(windSpeed:chanceOfRain:) the parameters and structure properties have the same names windSpeed and chanceOfRain. Contrary to previous case, now you cannot remove self keyword, because it would create an ambiguity between the parameter and property names.

self helps making an explicit distinction between parameters (windSpeed and chanceOfRain used without self) and structure properties (self.windSpeed and self.chanceOfRain, accessed with self).

Looking at the assignment windSpeed = windSpeed, how Swift can understand which variable is a parameter and which is a property? It's an ambiguity, so Swift plainly decides that you mean only the parameters.

As result an error is thrown: cannot assign to value: 'windSpeed' is a 'let' constant. It happens because let constant is assigned to itself windSpeed = windSpeed, which is not allowed.

2. To be, or not to be

There were plenty of discussions about the obligatory usage of self to access properties, or contrary to skip self.

The obligatory usage of self brings the benefits of consistency and favors clarity over brevity. You can clearly see the difference between the instance properties (that are prefixed with self.) from locally defined variables. Maybe...

In my opinion, when you have troubles to distinguish instance properties from local variables within a method: you have a different, deeper problem.

When a structure or class has an excessive number of properties (so called God object), you're probably breaking the Single responsibility principle.
If a method uses a big number of these properties and declares correspondingly many local variables, then such method does too many things. Using an explicit self to distinguish somehow properties from variables is a temporary workaround for a bad code.

It should not be that way.

Now imagine a well designed structure or class, which has a single responsibility. It contains only strictly necessary properties. A well written method is performing one determined action and as result its code is simple and obvious.
Surely you don't have the problem to distinguish local variables from instance properties in such a method. The usage of self may be even discouraged, since your adding to obvious code redundant explanations.

So design your classes and structures well, and don't let the methods grow to thousands of lines of code. Then you can omit self without difficulties, and your code becomes even more expressive and concise.

3. Access type properties and methods

self refers to a type (rather than to an instance) when used in a type method.

I find great that Swift allows 3 ways to access static properties. Use the one you like!

4. Access instance properties and methods in a closure

A closure is a block of code that can be referenced, passed around and invoked when necessary. A closure has access to variables from the environment where it was defined, also called the closure scope.

Sometimes you need to define a closure in a method. The closure can access the local method variables. What's more important you have to explicitly write self to access instance properties or methods within the closure.

Collection is a class that holds some prime numbers.
The method getAppendClosure() returns a closure that when invoked appends a new number to the collection. To access numbers property within the closure you have to explicitly use self keyword: { self.numbers.append($0) } .

The explicit use of self in a closure is an intentional design. Because closure captures the scope variables, including self reference, you may create a strong reference cycle between the closure and self. And you should beware of this potential problem.

To create a strong reference cycle, the common scenario is when a property of an instance is a closure that captures the instance itself. Let's see a sample:

When the variable leader is assigned with nil, normally the instance should be deinitianilazied. You can expect deinit method to be called that prints "Person deinitialized" message. However this does not happen.

The strong reference cycle creates the problem.

The instance holds the closure reference leader.sayMyName and simultaneously the closure captures and holds the instance reference { return self.name }. Under such circumstances the reference cycle cannot be broken and as result both leader instance and the closure cannot be deallocated.

The solution is to define inside the closure a capture list and mark self as an unowned reference. Let's fix the previous example:

Notice that [unowned self] is added in the closure, which marks self as an unowned reference. Now the closure does not keep a strong reference to self instance. The strong reference cycle between instance and closure is no longer created.

Since leader instance is not necessary leader = nil, the memory is deallocated correctly. The deinitializer deinit is called as expected, which prints "Person deinitialized" message to the console.

The method push(:) returns the current instance self. This enables the method chaining calls to push multiple elements 8, 10 and 2 at once into the stack.
Notice that @discardableResult attribute for push(:) method suppresses the warning that the result of the last method call in the chain is unused.

Enumeration case

To find what case holds the enumeration within its method, you can easily query self property with a switch statement.

For example, let's get a string message that describes the enumeration cases:

In the mutating method stop() the assignment self = Movement(speed: 0) modifies the current instance to a new one.

5. Conclusion

self is a property on the instance that refers to itself. It's used to access class, structure and enumeration instance within methods.

When self is accessed in a type method (static func or class func), it refers to the actual type (rather than an instance).

Swift allows to omit self when you want to access instances properties. My advice is to rely on shortness and skip self whenever possible.

When a method parameter have the same name as instance property, you have to explicitly use self.myVariable = myVariable to make a distinction.
Notice that method parameters have a priority over instance properties.

Do you think self should be omitted or kept? Feel free to write your opinion in the comments section below!