suvera-dev ๐Ÿฅฆ

Swift ) Closure ๋ณธ๋ฌธ

Language/Swift

Swift ) Closure

suvera 2022. 2. 9. 01:41

์˜ค๋Š˜์€ ์Šคํ„ฐ๋”” ์นœ๊ตฌ๋“ค๊ณผ ํ•จ๊ป˜ ํด๋กœ์ €์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๊ณต๋ถ€ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค ! 

 

๐ŸŒ€Closure ๋ž€? 

- ์ผ์ • ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์˜ ๋ธ”๋ก์œผ๋กœ ๋ชจ์•„๋†“์€ ๊ฒƒ

- func ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งŒ๋“ค์—ˆ๋˜ ํ•จ์ˆ˜ : named Closure

- ์ผ๋ฐ˜์ ์ธ ํด๋กœ์ € : Unnamed Closure๋ฅผ ์ง€์นญ 

 

{ (Parameters) -> Return Type in
  ์‹คํ–‰ ๊ตฌ๋ฌธ
}

 

๐ŸŒฟ1๊ธ‰ ๊ฐ์ฒด๋กœ์„œ์˜ ํŠน์ง• 

- ํด๋กœ์ €๋ฅผ ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜์— ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์œผ๋กœ ํด๋กœ์ €๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 


 

์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ Closure์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์˜ ์ฐจ์ด

: Closure๋Š” ํ•จ์ˆ˜๋ฅผ func ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ์„ ์–ธํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

- ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์‚ฌ์šฉ

var counter = 0
func addCounter() {
  counter += 1
}
addCounter()
addCounter()

print(counter) // ๊ฒฐ๊ณผ 2

์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•จ์ˆ˜๋ช…์„ ์„ค์ •(addCounter)ํ•˜๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜๋ช…์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ์ทจํ•ฉ๋‹ˆ๋‹ค.

 

 

- Closure ์‚ฌ์šฉ

var counter = 0
let addCounter = {
    counter += 1
}
addCounter()
addCounter()

print(counter) // ๊ฒฐ๊ณผ 2

Closure๋Š” ๋ณ€์ˆ˜์— ๊ฐ’์„ ์„ ์–ธํ•˜๋Š” ๋Œ€์‹ ์— ๋ณ€์ˆ˜์— ํ•จ์ˆ˜ ๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” addCounter ๋ณ€์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ถœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(addCounter() ํ˜•ํƒœ)

 

 

 


 

- Inline Closure : ํ•จ์ˆ˜๋กœ ๋”ฐ๋กœ ์ •์˜๋œ ํ˜•ํƒœ๊ฐ€ ์•„๋‹Œ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ํ˜•ํƒœ์˜ ํด๋กœ์ €

let reverseNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2})

์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ์—์„œ ํด๋กœ์ €์˜ ์ถ•์•ฝ ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค 

ํƒ€์ž…, ๋ฐ˜ํ™˜ํ‚ค์›Œ๋“œ, ์ธ์ž์ด๋ฆ„์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค 

// ํƒ€์ž… ์ƒ๋žต : ์ฝ”๋“œ์˜ ๋ชจํ˜ธ์„ฑ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ํƒ€์ž…์„ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๋•Œ๋„ ์žˆ๋‹ค.
let reverseNames = names.sorted(by: {s1, s2 in return s1 > s2})
// ๋ฐ˜ํ™˜ ํ‚ค์›Œ๋“œ ์ƒ๋žต 
let reverseNames = names.sorted(by: {s1, s2 in s1 > s2}) 
// ์ธ์ž ๊ฐ’์„ ์ถ•์•ฝ : $0 ๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ 
let reversedNames = names.sorted(by: { $0 > $1 })
// ์—ฐ์‚ฐ์ž ๋ฉ”์†Œ๋“œ : ์—ฐ์‚ฐ์ž๋งŒ ๋‚จ๊ธธ ์ˆ˜ ์žˆ์Œ
let reversedNames = names.sorted(by: > )

 

- Trailing closure (ํ›„ํ–‰ ํด๋กœ์ €): ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ „๋‹ฌ๋˜๋Š” ํด๋กœ์ €

์ธ์ž๋กœ ํด๋กœ์ €๋ฅผ ๋„ฃ๊ธฐ๊ฐ€ ๊ธธ๋‹ค๋ฉด ํ›„ํ–‰ ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜์˜ ๋’ค์— ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ! 

๋งŒ์•ฝ ํด๋กœ์ € ๋‚ด๋ถ€์— ์—ฌ๋Ÿฌ ์ค„์˜ ์‹คํ–‰ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ›„ํ–‰ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค 
๋งˆ์ง€๋ง‰ ์ „๋‹ฌ ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ํด๋กœ์ €์—๋งŒ ํ•ด๋‹น๋œ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ต !

let reversedNames = names.sorted { $0 > $1 }
let reversedNames = names.sorted { (s1: String, s2: String) -> Bool in return s1 > s2 }

 


์˜ˆ์‹œ - Closure๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ 

- ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›๋Š” VC์— ํ”„๋กœํผํ‹ฐ ์„ ์–ธ 

    var categoryId: Int
    var titleText: String
    var iconImageId: Int

- ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” Cell์—์„œ ํด๋กœ์ € ์„ ์–ธ -> Cell ์•ˆ์— ์žˆ๋Š” ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ํด๋กœ์ €๊ฐ€ ์‹คํ–‰ ๋˜๋„๋ก ! 

var presentEditCategoryClosure: (() -> Void)?

    private func bind() {
        editButton.rx.tap
            .bind(onNext: { [weak self] in
                self?.presentEditCategoryClosure?()
            })
            .disposed(by: disposeBag)
    }

- CollectionViewDataSource ์—์„œ Cell ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์ •ํ•  ๋•Œ ์‹ค์ œ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž‘์„ฑ 

func collectionView(_ collectionView: UICollectionView,
                        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(forIndexPath: indexPath) as CategoryCollectionViewCell
        
        cell.configure(type: .manage)
        cell.update(data: categories[indexPath.row])
        cell.presentEditCategoryClosure = {
            let categoryId = self.categories[indexPath.row].id ?? 0
            let titleText = self.categories[indexPath.row].title ?? ""
            let imageId = self.categories[indexPath.row].imageId ?? 0
            
            self.navigationController?.pushViewController(editCategory, animated: true)
        }

 

- Alert : ํ™•์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ Closure ์‚ฌ์šฉ

extension UIViewController {
    func makeAlert(title: String,
                   message: String,
                   okAction: ((UIAlertAction) -> Void)? = nil,
                   completion : (() -> Void)? = nil) {
        let alertViewController = UIAlertController(title: title,
                                                    message: message,
                                                    preferredStyle: .alert)
        let okAction = UIAlertAction(title: "ํ™•์ธ", style: .default, handler: okAction)
        alertViewController.addAction(okAction)
        self.present(alertViewController, animated: true, completion: completion)
    }
}
self.makeAlert(title: "์นดํ…Œ๊ณ ๋ฆฌ ์ˆ˜์ •", message: "์นดํ…Œ๊ณ ๋ฆฌ ์ˆ˜์ • ์„ฑ๊ณต", okAction: { [weak self] _ in
    self?.titleText = self?.categoryTitleTextField.text ?? ""
    self?.sendEditData?()
    self?.navigationController?.popViewController(animated: true)
})

 

๐Ÿ”–์ฐธ๊ณ ํ•œ ์‚ฌ์ดํŠธ

 

 

์˜ค๋Š˜์˜ Swift ์ƒ์‹ (Closure)

ํด๋กœ์ €(Closure)๋ž€?

medium.com

 

Swift Closure

Swift์˜ closure์— ๋Œ€ํ•ด ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

hcn1519.github.io

 

๐Ÿ”– ๊ฐ™์ด ์Šคํ„ฐ๋””ํ•œ ์นœ๊ตฌ๋“ค์˜ ํ‹ฐ์Šคํ† ๋ฆฌ

 

 

[iOS/Swift] Closure์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

๋“ค์–ด๊ฐ€๋ฉฐ ํด๋กœ์ €๋ž€ ์ด๋ฅธ๋ฐ” ์ด๋ฆ„ ์—†๋Š” ํ•จ์ˆ˜, โ€œ์ต๋ช… ํ•จ์ˆ˜"๋กœ ๋ถˆ๋ฆฌ๋Š” ์ฝ”๋“œ๋ธ”๋Ÿญ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” iOS ๊ฐœ๋ฐœ์„ ํ•˜๋ฉฐ ์ •~๋ง์ •๋ง ๋งŽ์ด ์‚ฌ์šฉํ–ˆ๋˜ ๋ฌธ๋ฒ•์ธ ํด๋กœ์ €์— ๋Œ€ํ•ด ํƒ๊ตฌํ•ด๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ง€

osoomoovo.tistory.com

 

๐Ÿ”– ์ถ”๊ฐ€์ ์œผ๋กœ ๊ณต๋ถ€ํ• ๋งŒํ•œ ๋‚ด์šฉ

๋‹ค์Œ์—๋Š” Escaping Closure์™€ Completion Handler์— ๋Œ€ํ•œ ๋‚ด์šฉ๋„ ์ •๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹น 

 

 

[SWIFT] Escaping Closure(ํƒˆ์ถœ ํด๋กœ์ €)

ํด๋กœ์ €์˜ ๊ธฐ๋ณธ์— ๋Œ€ํ•ด ํฌ์ŠคํŒ…์„ ํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ์š”. ์ด๋ฒˆ์—๋Š” ํด๋กœ์ € ํ™œ์šฉ์— ๋Œ€ํ•ด ํฌ์ŠคํŒ…์„ ํ•ด๋ณผ๊ฒŒ์š”. ์ด์ „ ํฌ์ŠคํŒ…์„ ์•ˆ๋ณด์‹  ๋ถ„์€ ๋ณด๊ณ  ์˜ค์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”. [SWIFT] Closure(ํด๋กœ์ €) (1/2) ์˜ค๋Š˜์€

dongminyoon.tistory.com

 

[iOS] Completion Handler

Completion Handler ๋ณธ ๋ฌธ์„œ์—๋Š” ํ‰์†Œ์— ๊ณต๋ถ€๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ํ•œ๋ฒˆ ์ •๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋˜ Completion Handler ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๊ธฐ์žฌํ•œ๋‹ค. Prerequisite Completion Handler ๊ฐœ๋…์€ ์•Œ๋ฉด ์•Œ์ˆ˜๋ก ์–ด๋ ค์šด ๊ฐœ๋…์ด๋‹ค....

duwjdtn11.tistory.com

 

Swift Escaping Closure ์ดํ•ดํ•˜๊ธฐ

Swift์˜ Escaping Closure์— ๋Œ€ํ•ด ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

hcn1519.github.io

Comments