Sobes.tech
Junior

Mi az a lezárás?

sobes.tech MI

Válasz az MI-től

A Swiftben a zárójel (closure) egy önálló funkcionális egység ({}), amely átadható és használható a kódban. A zárójelek képesek elfogni és tárolni hivatkozásokat bármilyen állandóra vagy változóra a kontextusból, ahol definiálva vannak.

Használati példák:

  • Függvények argumentumaiként (pl. Completion Handlers).
  • A kollekciók iterálásakor történő viselkedés meghatározására (pl. map, filter, reduce, sorted metódusok használatával).
  • Kód késleltetett végrehajtására.

Szintaxis:

// Alap szintaxis
{ (paraméterek) -> visszatérési típus in
    utasítások
}

// Egy példa zárójel, amely Int-et fogad és String-et ad vissza
let integerToString: (Int) -> String = { (number: Int) -> String in
    return "Szám: \(number)"
}

Jellemzők:

  • Automatikus változó elfogás (capturing values).
  • A zárójelek típusainak explicit megadása nélkül is definiálhatók (szintaktikus cukor).
  • Rövidített paraméternevek használata ($0, $1 stb.).
  • A zárójel szintaxis (trailing closure syntax).

Változók elfogása:

A zárójel elfoghatja a környezetéből származó változókat. Alapértelmezés szerint hivatkozás szerint történik az elfogás. Ha a zárójel használata után a kiindulási változó már nem elérhető, a zárójel továbbra is hozzáférést biztosít hozzá.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0 // Külső környezetből származó változó
    let incrementer: () -> Int = { // Zárójel
        runningTotal += amount // Elfogja a runningTotal-t és az amount-ot
        return runningTotal
    }
    return incrementer
}

let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Kimenet: 10
print(incrementByTen()) // Kimenet: 20

Elfogási listák (Capture Lists):

Ezeket arra használják, hogy egyértelműen megadják, hogyan kell elfogni a változókat - érték szerint vagy hivatkozás szerint, valamint a ciklusok erős hivatkozásainak (retain cycles) elkerülésére.

class MyClass {
    var value = 0

    lazy var myClosure: () -> Void = { [self, value] in // self hivatkozás szerint, value érték szerint
        print("self.value értéke: \(self.value)")
        print("Elfogott érték: \(value)")
    }

    deinit {
        print("A MyClass példány felszabadult")
    }
}

Az erős hivatkozási ciklusok elkerülése érdekében a [weak self] vagy [unowned self] szintaxist használják.

class ViewController {
    var dataFetcher: DataFetcher?

    func fetchData() {
        dataFetcher?.fetch { [weak self] result in // gyenge hivatkozás self-re
            guard let self = self else { return } // létezés ellenőrzése
            // eredmény kezelése
        }
    }
}

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

    func fetch(completion: @escaping (Result<String, Error>) -> Void) {
        self.completionHandler = completion
        // Aszinkron művelet...
    }
}