Crack Any Swift Interview: A Complete Guide to Mastering Key iOS Concepts PART 1

inspirethedev@gmail.com

Classes vs Structures

Struct is like a Tiffin Box Copy:

Class is like a Google Doc:

Memory Difference: Stack vs Heap

Mutability Rules

Inheritance

ARC — Automatic Reference Counting

Performance

When to Use Class vs Struct

Struct

  • You’re modeling simple data (like User, Post, Product)
  • You want to keep things immutable or copy-safe
  • You don’t need inheritance or identity

Class

  • You need inheritance, polymorphism, or reference-sharing
  • You’re working with UIKit components
  • You’re managing shared logic (like singleton managers, services)

Example

Struct:

struct Player {
    var name: String
    var team: String
    var runs: Int
}

var player1 = Player(name: "Virat Kohli", team: "India", runs: 50)
var player2 = player1  // Creates a copy

player2.runs = 75

print(player1.runs)  // Output: 50
print(player2.runs)  // Output: 75

Class :

class NetworkManager {
    var isConnected: Bool = false
}

let manager1 = NetworkManager()
let manager2 = manager1  // Shares the same instance

manager2.isConnected = true

print(manager1.isConnected)  // Output: true
print(manager2.isConnected)  // Output: true

Closure

  • Capture values from their surrounding context
  • Be stored as variables
  • Be used for callback logic
let greet: (String) -> String = { (name) in
    return "Hello, \(name)"
}

print(greet("Swift")) // Output: Hello, Swift

Why Use Closures?

  • To pass behavior as a value (functional programming)
  • To write completion handlers (network requests, animations)
  • To make code more flexible and reusable

Key Closure Concepts

Trailing Closures

func doSomething(task: () -> Void) {
    task()
}
// Call using trailing closure
doSomething {
    print("Task done")
}

Capturing Values

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let counter = makeCounter()
print(counter()) // 1
print(counter()) // 2

Escaping vs Non-Escaping Closures

Non-Escaping (default):

func doWork(closure: () -> Void) {
    closure() // called inside
}

Escaping:

func fetchData(completion: @escaping () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        completion()
    }
}

Autoclosures:

func logIfNeeded(_ message: @autoclosure () -> String) {
    print("LOG: \(message())")
}

logIfNeeded("App started") // looks like a normal string, but it's a closure

Closures and Memory Leaks

class ViewModel {
    var name = "Swift"
    
    func loadData(completion: @escaping () -> Void) {
        DispatchQueue.main.async { [weak self] in
            print(self?.name ?? "No name")
            completion()
        }
    }
}

OPTIONALS

var address: String?  // might be nil

Unwrapping Optionals

Force Unwrapping (!)

let name: String? = "Rahul"
print(name!)  // Output: Rahul

Optional Binding (if let / guard let)

if let

if let safeName = name {
    print("Hello, \(safeName)")
} else {
    print("Name is nil")
}

guard let

func greet(_ name: String?) {
    guard let unwrapped = name else {
        print("No name provided")
        return
    }
    print("Hello, \(unwrapped)")
}

Nil Coalescing Operator (??)

let userCity: String? = nil
let finalCity = userCity ?? "Mumbai"
print(finalCity)  // Output: Mumbai

Optional Chaining

let user: User? = getUser()
let street = user?.address?.street

Generics

func swapValues<T>(a: inout T, b: inout T) {
    let temp = a
    a = b
    b = temp
}

Generics in Functions

func printArray<T>(items: [T]) {
    for item in items {
        print(item)
    }
}

printArray(items: [1, 2, 3])
printArray(items: ["a", "b", "c"])

Generics in Structs and Classes

struct Box<T> {
    var value: T
}

let intBox = Box(value: 123)
let stringBox = Box(value: "Swift")

Type Constraints with Generics

func findLargest<T: Comparable>(a: T, b: T) -> T {
    return a > b ? a : b
}

findLargest(a: 7, b: 3)         // Works
findLargest(a: "cat", b: "dog") // Works

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *