Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An instance method is a function encapsulated within a specific class, structure, or enumeration that operates on a specific instance of that type. It defines the behavior associated with an object or value, possessing implicit access to the instance’s stored properties, computed properties, and other instance methods.

Syntax and Context

Instance methods are declared using the func keyword within the lexical scope of the type definition. They are invoked using dot syntax on an instantiated object.
class Counter {
    var count: Int = 0
    
    func increment(by amount: Int) {
        count += amount
    }
}

let myCounter = Counter()
myCounter.increment(by: 5)

The Implicit self Property

Every instance of a type has an implicit property called self, which is a reference to the instance itself. Within an instance method, self is used to access properties and methods of the current instance. While Swift allows omitting self when accessing properties, it is required when disambiguating between an instance property and a method parameter with the same name.
class Point {
    var x: Double = 0.0
    
    func updateX(x: Double) {
        // 'self.x' refers to the property, 'x' refers to the parameter
        self.x = x 
    }
}

Value Types and the mutating Keyword

In Swift, structures and enumerations are value types. By default, the properties of a value type cannot be modified from within its instance methods. To enable property mutation, the instance method must be explicitly declared with the mutating keyword. Under the hood, a mutating method receives the implicit self property as an inout parameter. This allows the method to mutate the properties or even assign an entirely new instance to self, overwriting the existing value in memory.
struct StateMachine {
    var state: Int = 0
    
    mutating func advance() {
        state += 1
    }
    
    mutating func reset() {
        self = StateMachine(state: 0) // Reassigning self
    }
}
Note: Classes are reference types; therefore, their instance methods can mutate properties without the mutating keyword.

Method Dispatch Mechanisms

The way Swift invokes an instance method depends on the type it belongs to and its declaration modifiers:
  1. Static (Direct) Dispatch: Used for instance methods on value types (structs and enums), final classes, and methods declared in class extensions. The compiler determines the memory address of the method at compile time, resulting in highly optimized, inlineable execution.
  2. Dynamic (Table) Dispatch: Used for standard instance methods in non-final classes. Swift uses a Virtual Method Table (vtable) at runtime to look up the correct implementation of the method, allowing for inheritance and method overriding.
  3. Message Dispatch: Used when an instance method is marked with @objc dynamic. The method invocation is deferred to the Objective-C runtime using objc_msgSend.

Instance Methods as Closures

In Swift, instance methods are essentially curried functions. You can reference an instance method without invoking it, either bound to a specific instance or unbound. Bound Reference: Referencing a method on a specific instance yields a closure that captures the instance.
let counter = Counter()
let boundMethod: (Int) -> Void = counter.increment(by:)
boundMethod(10) // Executes on 'counter'
Unbound Reference: Referencing a method directly on the type yields a closure where the first parameter is the instance itself.
let unboundMethod: (Counter) -> (Int) -> Void = Counter.increment(by:)
let anotherCounter = Counter()
unboundMethod(anotherCounter)(5) // Explicitly passes the instance
Master Swift with Deep Grasping Methodology!Learn More