Ի՞նչ է փակումը։
sobes.tech AI
Պատասխան AI-ից
Swift- ում փակումը (closure) ինքնաբավ ֆունկցիոնալ բլոկ է ({}), որը կարող է փոխանցվել և օգտագործվել կոդում: Փակումները կարող են բռնել և պահել հղումներ ցանկացած հաստատունների և փոփոխականների դեպի կոնտեքստ, որտեղ դրանք սահմանված են:
Օգտագործման օրինակներ:
- Ֆունկցիաների արգումենտներ (օրինակ, Completion Handlers)
- Կոլեկցիաների անցնելու ժամանակ վարքագծի սահմանման համար (օրինակ, օգտագործելով
map,filter,reduce,sortedմեթոդները) - Կոդի հետաձգված կատարման համար
Սինտաքսիս:
// Հիմնական սինտաքսիս
{ (պարամետրեր) -> վերադարձվողՏիպ in
արտահայտություններ
}
// Փակման օրինակ, որը ընդունում է Int և վերադարձնում String
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Թիվը՝ \(number)"
}
Հատկանիշներ:
- Ավտոմատ բռնում փոփոխականներ (capturing values)
- Փակման սահմանման հնարավորությունը առանց բացահայտ տիպերի նշման (սինտաքսիկ շաքար)
- Կրճատ անունների օգտագործում ($0, $1 և այլն)
- Փակման սինտաքսիս (trailing closure syntax)
Փակման մեջ փոփոխականների բռնում:
Փակումը կարող է բռնել իր շրջապատից փոփոխականներ: Դրա նախնական ձևը՝ բռնումը կատարվում է հղումով: Եթե փակումը օգտագործվում է այն ժամանակ, երբ սկզբնական փոփոխականը դուրս է եկել տեսանելիության տարածքից, փակումը դեռ պահպանում է նրա հասանելիությունը:
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Բացակետային կոնտեքստից փոփոխական
let incrementer: () -> Int = { // Փակում
runningTotal += amount // Բռնում է runningTotal և amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Արտածում՝ 10
print(incrementByTen()) // Արտածում՝ 20
Բռնման ցանկեր (Capture Lists):
Օգտագործվում են հստակ նշելու, թե ինչպես պետք է բռնվեն փոփոխականները՝ արժեքով կամ հղումով, ինչպես նաև՝ ուժեղ հղումների ցիկլերը խուսափելու համար:
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // Բռնում self հղումով, value արժեքով
print("self.value-ի արժեքը՝ \(self.value)")
print("Բռնված արժեք՝ \(value)")
}
deinit {
print("MyClass օբյեկտը ազատված է")
}
}
Կարևոր է՝ ուժեղ հղումներից (strong reference cycles) խուսափելու համար օգտագործել [weak self] կամ [unowned self]:
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // թույլ հղում self-ին
guard let self = self else { return } // ստուգում՝ արդյոք self-ը գոյություն ունի
// արդյունքի մշակումը
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Ասինխրոն գործողություն...
}
}