Lesson 62Classes

Reference Types

Understanding Reference Types

When you assign a class instance to another variable or pass it to a function, you're creating a new reference to the same object - not a copy!

Visual Representation

let dog1 = Dog("Buddy") → [Memory: 0x123]
let dog2 = dog1        → [Memory: 0x123] ← Same!
Both variables point to the SAME memory location

Identity Operators

=== (Identical)

Checks if two references point to the same instance

!== (Not Identical)

Checks if references point to different instances

let with Classes

Important: Using let with a class prevents reassigning the reference, but you can still modify the object's properties!

let player = Player()
player.score = 100  // OK!
player = Player()   // ERROR!
main.swift
// REFERENCE TYPES
// Classes share the SAME instance in memory

// REFERENCE BEHAVIOR DEMO
class Dog {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let dog1 = Dog(name: "Buddy", age: 3)
let dog2 = dog1  // Both point to SAME dog!

dog2.name = "Max"  // Change through dog2

print(dog1.name)  // Max (dog1 also changed!)
print(dog2.name)  // Max

// IDENTITY OPERATORS
// === checks if two references point to same instance
// !== checks if they point to different instances

let dog3 = Dog(name: "Max", age: 3)

print(dog1 === dog2)  // true (same instance)
print(dog1 === dog3)  // false (different instances)
print(dog1 !== dog3)  // true

// PASSING CLASSES TO FUNCTIONS
class Counter {
    var count = 0

    func increment() {
        count += 1
    }
}

func incrementCounter(_ counter: Counter) {
    counter.increment()  // Modifies original!
}

let myCounter = Counter()
incrementCounter(myCounter)
incrementCounter(myCounter)
print(myCounter.count)  // 2

// MULTIPLE REFERENCES
class Player {
    var name: String
    var score: Int

    init(name: String, score: Int = 0) {
        self.name = name
        self.score = score
    }
}

var currentPlayer = Player(name: "Alice", score: 100)
var highScorePlayer = currentPlayer  // Same player!
var backupPlayer = currentPlayer     // Still same player!

currentPlayer.score = 200

print(highScorePlayer.score)  // 200 (all changed)
print(backupPlayer.score)     // 200

// ARRAYS OF CLASSES
let players = [
    Player(name: "Alice", score: 100),
    Player(name: "Bob", score: 85)
]

let topPlayers = players  // Same references!

topPlayers[0].score = 150
print(players[0].score)  // 150 (modified!)

// CAREFUL WITH let
let fixedPlayer = Player(name: "Charlie", score: 50)
// fixedPlayer = Player(...)  // ERROR: can't reassign
fixedPlayer.score = 100  // OK: can modify properties!

// The 'let' only prevents reassigning the reference,
// NOT modifying the object's properties!

Try It Yourself!

Create two references to the same User object. Modify through one reference and verify the change is visible through the other!