What is "self" used for in Swift?
Asked Answered
A

10

49

I am new to Swift and I'm wondering what self is used for and why.

I have seen it in classes and structures but I really don't find them essential nor necessary to even mention them in my code. What are they used for and why? In what situations it's necessary to use it?

I have been reading lots of questions and answers for this question but none of them fully answers my questions and they always tend to compare it with this as in Java, with which I'm not familiar whatsoever.

Atingle answered 10/11, 2014 at 0:26 Comment(2)
Well, it is the same as this in Java, this in Javascript, self in Objective-C. You need to get familiar with that concept...Langrage
Are you really asking what self means or why you can sometimes (often) leave it out (as it will be implied)?Langrage
O
37

You will also use self a lot when creating your extensions, example:

extension Int {
    func square() -> Int {
        return self * self
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func squareMe() {
        self = self * self
    }
}
let x = 3
let y = x.square()  
println(x)         // 3
printlx(y)         // 9

now let's say you want to change the var result itself you have to use the mutating func to make change itself

var z = 3

println(z)  // 3

now let's mutate it

z.squareMe()

println(z)  // 9

// now let's see another example using strings :

extension String {
    func x(times:Int) -> String {
        var result = ""
        if times > 0 {
            for index in 1...times{
                result += self
            }
            return result
        }
        return ""
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func replicateMe(times:Int){
        if times > 1 {
            let myString = self
            for index in 1...times-1{
                self = self + myString
            }
        } else {
            if times != 1 {
                self = ""
            }
        }
    } 
}


var myString1 = "Abc"
let myString2 = myString1.x(2)

println(myString1)         // "Abc"
println(myString2)         // "AbcAbc"

now let's change myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"
Oswald answered 10/11, 2014 at 3:54 Comment(0)
O
69

Yes it is the same as this in Java and self in Objective-C, but with Swift, self is only required when you call a property or method from a closure or to differentiate property names inside your code, such as initializers. So you can use almost all of your class components safely without using self unless you are making the call from a closure.

“The self Property Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself. You use the self property to refer to the current instance within its own instance methods.

The increment() method in the example above could have been written like this:

func increment() {
    self.count += 1
}

In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method. This assumption is demonstrated by the use of count (rather than self.count) inside the three instance methods for Counter.

The main exception to this rule occurs when a parameter name for an instance method has the same name as a property of that instance. In this situation, the parameter name takes precedence, and it becomes necessary to refer to the property in a more qualified way. You use the self property to distinguish between the parameter name and the property name.

Here, self disambiguates between a method parameter called x and an instance property that is also called x:”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2 Prerelease).”


This is how Ray Wenderlich recommends the use of self in Swift for their tutorials:

Use of Self

For conciseness, avoid using self since Swift does not require it to access an object's properties or invoke its methods.

Use self when required to differentiate between property names and arguments in initializers, and when referencing properties in closure expressions as required by the compiler:

class BoardLocation {
  let row: Int, column: Int

  init(row: Int, column: Int) {
    self.row = row
    self.column = column

    let closure = {
      println(self.row)
    }
  }
}

And this is GitHub's recommendations on self for their applications:

Only explicitly refer to self when required

When accessing properties or methods on self, leave the reference to self implicit by default:

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

Only include the explicit keyword when required by the language — for example, in a closure, or when parameter names conflict:

extension History {
    init(events: [Event]) {
        self.events = events
    }

    var whenVictorious: () -> () {
        return {
            self.rewrite()
        }
    }
}

Rationale: This makes the capturing semantics of self stand out more in closures, and avoids verbosity elsewhere.

Orfinger answered 10/11, 2014 at 0:38 Comment(7)
Why is it deemed necessary in closures when there is no hiding happening?Mallorymallow
I supposed it has to be use to keep the scope, but I'm just guessing here, need to validate that info =)Orfinger
Concerning comments about closures: self if used for the code to be readable, to make the properties usage explicit. In Java this could be used in the same way for the same reason.Vaenfila
While I respect Ray Wenderlichs team very much for their work, I think they are not the top reference for clean code. In general I would recommend to use self to clarify on the first glance, if code is local or not.Warhol
You shouldn't write code just for clarity, use documentation instead.Orfinger
I would say it's similar to this in Java but not the same. See my post for explanation: #34500390Indented
It is necessary in closures because of closures' capture semantics: closures are reference types and therefore can produce strong reference cycles. The programmer may not explicitly realize that the closure has a strong reference to self if self never appears in the closure's code. Roughly, you would have such a strong reference cycle in a class with a property holding a closure and the closure referring to self. This may cause dangling references (memory never freed) but can be avoided with unowned references and closure capturesAgitprop
O
37

You will also use self a lot when creating your extensions, example:

extension Int {
    func square() -> Int {
        return self * self
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func squareMe() {
        self = self * self
    }
}
let x = 3
let y = x.square()  
println(x)         // 3
printlx(y)         // 9

now let's say you want to change the var result itself you have to use the mutating func to make change itself

var z = 3

println(z)  // 3

now let's mutate it

z.squareMe()

println(z)  // 9

// now let's see another example using strings :

extension String {
    func x(times:Int) -> String {
        var result = ""
        if times > 0 {
            for index in 1...times{
                result += self
            }
            return result
        }
        return ""
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func replicateMe(times:Int){
        if times > 1 {
            let myString = self
            for index in 1...times-1{
                self = self + myString
            }
        } else {
            if times != 1 {
                self = ""
            }
        }
    } 
}


var myString1 = "Abc"
let myString2 = myString1.x(2)

println(myString1)         // "Abc"
println(myString2)         // "AbcAbc"

now let's change myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"
Oswald answered 10/11, 2014 at 3:54 Comment(0)
D
19

In what situations it's necessary to use it

It is necessary to use it only when the name of a local variable overshadows the name of a property.

However, as a matter of style (and readability), I always use it:

  • I use it with property names, because otherwise I am left wondering what this variable is (since it is neither locally declared nor an incoming parameter).

  • I use it as the receiver of function (method) calls, in order to differentiate such methods from top-level or local functions.

Duma answered 10/11, 2014 at 1:22 Comment(1)
thanks matt. these days I have the feeling that the "don't need" pattern is more important than thinking of readability and good style. imho style is more important.Warhol
C
12

This is why we need self.

When we define a class, like:

class MyClass {
    func myMethod()
}

We are creating a "Class Object". Yes, Class is an object too.

Then no matter how many instances are created using the class, all instances will have a reference pointer to its Class Object.

You can imagine that all instance methods defined by the Class are in the Class Object, and there will be only one copy of them.

enter image description here

That means all instances created using the Class are sharing the same method.

Now imagine you are the myMethod in the Class Object, and because you are shared for all instances, you must have a way to tell which instance you are working on.

When someone says instance1.myMethod(), it means "Hi! myMethod, please do your work and instance1 is the object you are working on".

To reference the object that the caller sent to you, use self.

“In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method.”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/tw/jEUH0.l

Cystoid answered 10/11, 2014 at 3:3 Comment(1)
What you describe is the general approach for object orientation and instances of objects. You still don't need self here as this is implicitly handled by the compiler (with self being a pointer to your VMT or similar structures for a particular class instance, aka object).Gratification
I
9

The reserved word self in Swift is similar to this but it's not the same as in Java or JavaScript.

As @Dave Gomez correctly quoted:

Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself.

Here lies one of the main differences, because:

  1. "Every instance" in Swift (at least for now) is almost every-thing.
  2. In Java, for example, you can only use the word this inside an instance scope, in Swift you can use it almost every-where.

Here are a few examples:

//Example 1:
var x="foo"
x.self="bar".self//compiles and run

//Example 2:
print.self(x);//compiles and run

//Example 3:
func myOther(self otherSelf:Person){}
myOther(self: personObject);//compiles and run

//Example 4:
class Foo{
      var bar=""
      init(){
          self.addSome()//this would be the same in Java
      }
      func addSome(){
          //But definitely not this:
          self.self.bar.self.self="some".self.self
      }
}
//Guess what - also compiles and run...
let f=Foo()
print(f.bar)

See : Why 'self.self' compiles and run in swift for more information.

Indented answered 28/7, 2016 at 21:33 Comment(0)
S
4

I arrived at this question while searching for self as a class function, which looks like this: Int.self, String.self, or YourClass.self

Previously, as near as I can tell, only Dmitri Pavlutin's answer touches on this, when he said:

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

When self is used this way, it actually returns what in Swift is called a Metatype. You can read the Swift documentation page on Types for more information.

There is also an article with more details about using and understanding metatypes called "What's .self, .Type and .Protocol? Understanding Swift Metatypes" on swiftrocks.com.

Sharpeyed answered 7/8, 2019 at 22:29 Comment(0)
D
3

"How to use correctly 'self' keyword in Swift" explains self in detail.

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 like static func or class func, it refers to the actual type rather than an instance.

Swift allows omitting self when you want to access instances properties.

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

Dunson answered 14/11, 2016 at 7:42 Comment(0)
D
2

I'm a total noob at coding in general - and whilst these answers are great, from the perspective of a total noob who just wants it answered as practically as possible without all these difficult words and concepts, here's my Super Noob dumbed down version:

'self' is used because the coding application doesn't know which variable to use if you type the variable in the scope of your functions. It's all about the scope and making it clear which variable you're using if some other variable has the same name. Scope is the area inside the curly {} brackets. so for example:

{ scope1 {scope2} }

Here you don't need to use self:

class example {
    private var exampleVar = “this is the class scope variable”

    func x() {
        //You don't have to use self here
        print(exampleVar)
    }
}

Here you do need to use self:

class example {
        private var exampleVar = “this is the class scope variable”

        func x(_ exampleVar: String) {
            //It would be confusing which exampleVar is used here so you should use self
            print(exampleVar)
            print(self.exampleVar)
        }
}

There's also this situation:

class example {
    private var exampleVar = “this is the class scope variable”

    func x() {
        randomMethod { _ in
            //This is not the class scope here, so we need to use self here.
            //You will be flagged during build time of this if you don't use self.
            print(self.exampleValue)                     
        }
    }
}
Devonne answered 12/4, 2020 at 13:1 Comment(0)
A
1

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

When a method parameter has the same name as an instance property, you have to explicitly use self.myVariable = myVariable to make a distinction.

Notice that method parameters have a priority over instance properties.

    struct Weather {
let windSpeed: Int
  let chanceOfRain: Int
  init(windSpeed: Int, chanceOfRain: Int) {
    self.windSpeed = windSpeed
    self.chanceOfRain = chanceOfRain
  }

  func isDayForWalk() -> Bool {
    let comfortableWindSpeed = 5
    let acceptableChanceOfRain = 30
    return self.windSpeed <= comfortableWindSpeed
      && self.chanceOfRain <= acceptableChanceOfRain
  }

}
// A nice day for a walk
let niceWeather = Weather(windSpeed: 4, chanceOfRain: 25)  
print(niceWeather.isDayForWalk()) // => true
Astrakhan answered 5/7, 2018 at 7:4 Comment(0)
P
0

I have an elegant case for using self in Swift. I use it in blocks like this:

class MyBase {
   private var baseValue: Int = 100
   var block: ((Int)->())? = nil
   func baseMethod(anotherValue: Int) {
      guard let b = block else { return }
      b(baseValue + anotherValue)
   }
   ...
}

class MyClass {
   init()
   {
     // Define base class block. 
     // This may hold self in block causing memory leaks
     // if self is a strong reference
     block = {
       // indicate self is a weak reference 
       [weak self] (para) in
       // guaranty self existence
       guard let this = self else {return}

       let value = this.value1 + para
       // this call passes value to other obj's method
       this.obj.method(value) 
       return
     }
   }
   func callBaseBlock(otherValue: Int) {
     baseMethod(otherValue)
   }
   private var value1: Int = 1 // ini value
   private var obj: OtherClass // another class with method defined
   ...
   ...

}

This way, I guarantee that there will be no strong references to self in the block. The syntax is very clear. I use this way to prevent memory leaks.

Pulsatory answered 9/8, 2022 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.