Sobes.tech
Junior

Čo je to uzáver?

sobes.tech AI

Odpoveď od AI

Zatvorka (closure) v Swift je samostatný blok funkčnosti ({}), ktorý môže byť odovzdaný a použitý v kóde. Zatvorky môžu zachytiť a uložiť odkazy na akékoľvek konštanty a premenné z kontextu, v ktorom sú definované.

Príklady použitia:

  • Ako argumenty funkcií (napríklad, Completion Handlers).
  • Na definovanie správania pri prechádzaní kolekcií (napríklad, pomocou metód map, filter, reduce, sorted).
  • Na odložené vykonanie kódu.

Syntax:

// Základná syntax
{ (parametre) -> návratovýTyp in
    príkazy
}

// Príklad zatvorky, ktorá prijíma Int a vracia String
let integerToString: (Int) -> String = { (number: Int) -> String in
    return "Číslo: \(number)"
}

Vlastnosti:

  • Automatické zachytávanie premenných (capturing values).
  • Možnosť definovať zatvorky bez explicitného určenia typov parametrov a návratovej hodnoty (syntaktický cukor).
  • Použitie skrátených mien parametrov ($0, $1 a pod.).
  • Syntax zatvorky (trailing closure syntax).

Zachytávanie premenných:

Zatvorka môže zachytiť premenné zo svojho okolia. Podľa predvoleného správania sa zachytávanie vykonáva odkazom. Ak sa zatvorka používa po tom, čo pôvodná premenná opustila oblasť platnosti, zatvorka si stále zachová prístup k nej.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0 // Premenná z vonkajšieho prostredia
    let incrementer: () -> Int = { // Zatvorka
        runningTotal += amount // Zachytáva runningTotal a amount
        return runningTotal
    }
    return incrementer
}

let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Výstup: 10
print(incrementByTen()) // Výstup: 20

Zoznamy zachytávania (Capture Lists):

Používajú sa na explicitné určenie, ako majú byť premenné zachytené - hodnotou alebo odkazom, a tiež na zabránenie silných cyklov odkazov (retain cycles).

class MyClass {
    var value = 0

    lazy var myClosure: () -> Void = { [self, value] in // Zachytávanie self odkazom, value hodnotou
        print("Hodnota self.value: \(self.value)")
        print("Zachytená hodnota: \(value)")
    }

    deinit {
        print("Inštancia MyClass bola uvoľnená")
    }
}

Na prevenciu silných cyklov pri zachytávaní objektov tried sa používa syntax [weak self] alebo [unowned self].

class ViewController {
    var dataFetcher: DataFetcher?

    func fetchData() {
        dataFetcher?.fetch { [weak self] result in // slabá referencia na self
            guard let self = self else { return } // kontrola existencie self
            // spracovanie result
        }
    }
}

class DataFetcher {
    var completionHandler: ((Result<String, Error>) -> Void)?

    func fetch(completion: @escaping (Result<String, Error>) -> Void) {
        self.completionHandler = completion
        // Asynchrónna operácia...
    }
}