Deep_Dev
article thumbnail

๐Ÿ“Œ Delegate Pattern

Delegate ํŒจํ„ด์€ iOS์—์„œ ์ •๋ง ๋งŽ์ด ์“ฐ์ด์ง€๋งŒ, ๋ญ”์ง€ ๋ชจ๋ฅด๊ณ  ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ฅผ ์น˜๊ณ  ์žˆ๊ธฐ ์ œ์ผ ์‰ฌ์šด ๊ฒƒ๋“ค ์ค‘ ํ•˜๋‚˜์ธ ๊ฒƒ ๊ฐ™๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด, UITableView๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ UITableViewDataSource, UITableViewDelegate๋ฅผ ๋‹น์—ฐํ•˜๊ฒŒ ViewController์— ์ฑ„ํƒํ•˜๊ณค ํ•˜์ง€๋งŒ ์™œ ๊ผญ ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด UITableViewDataSource๋ฅผ ์ฑ„ํƒํ•ด์•ผ ํ•˜๋Š”์ง€, UITableViewDataSource์™€ UITableViewDelegate๋Š” ์™œ ํ”„๋กœํ† ์ฝœ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š”์ง€ ๋“ฑ๋“ฑ์„ ์„ค๋ช…ํ•˜๋Š” ๊ฑด ํŠนํžˆ๋‚˜ ์ดˆ์‹ฌ์ž์—๊ฒ ์‰ฝ์ง€ ์•Š์€ ์ผ์ด๋‹ค.

 

์• ํ”Œ์€ ์™œ ๊ทธ๋ ‡๊ฒŒ๋‚˜ ๋งŽ์€ UI์š”์†Œ๋“ค์— Delegate ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฑธ๊นŒ


ํ•ญ์ƒ ์ดํ•ดํ•œ ๋“ฏ ์•ˆ ํ•œ๋“ฏ, ์•„๋Š” ๋“ฏ ๋ชจ๋ฅด๋Š” ๋“ฏํ•œ Delegate ํŒจํ„ด์„ ์ดํ•ดํ•ด๋ณด์ž

 

๐Ÿ’ก Delegate Pattern ์ด๋ž€?

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์€ ๋ณดํ†ต ๊ฐ์ฒด๊ฐ€ ์ž์‹ ์˜ ์ฑ…์ž„์„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์œ„์ž„(delegate)ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋ผ๊ณ  ์„ค๋ช…๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ…Œ์ด๋ธ”๋ทฐ๋Š” ์…€์„ ํƒญํ–ˆ์„ ๋•Œ ์–ด๋–ค ํ–‰๋™์„ ํ• ์ง€์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์—๊ฒŒ UITableViewDelegate๋ฅผ ์‚ฌ์šฉํ•ด ์œ„์ž„ํ•œ๋‹ค.

ํ…Œ์ด๋ธ”๋ทฐ ์™ธ์—๋„ ์ฝœ๋ ‰์…˜๋ทฐ, ํ…์ŠคํŠธํ•„๋“œ ๋“ฑ ๋งŽ์€ UI์š”์†Œ๋“ค์ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์ฑ…์ž„์„ ์œ„์ž„ํ•˜๊ณ  ์žˆ๋‹ค.

 

 

์™œ ๊ตณ์ด “์œ„์ž„”์„ ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

 

๐Ÿ’ก UI์š”์†Œ์—์„œ์˜ Delegate Pattern

์‚ฌ์šฉ์ž๊ฐ€ ํ…Œ์ด๋ธ”๋ทฐ์˜ ์…€์„ ํƒญํ•˜๋Š” ์ƒํ™ฉ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž.

 

์…€์„ ํƒญํ•˜๋ฉด ํ…Œ์ด๋ธ”๋ทฐ๋Š” ํƒญ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๋Š”๋‹ค. ํ…Œ์ด๋ธ”๋ทฐ๊ฐ€ ํƒญ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์œผ๋ฉด delegate์˜ didSelectRowAt ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค. ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•˜์„ ๋•Œ ์–ด๋–ค ํ–‰๋™์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ delegate์—๊ฒŒ ์œ„์ž„ํ•œ ๊ฒƒ์ด๋‹ค.

๋ณดํ†ต์€ ViewController์— tableView.delegate = self์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ViewController self, ์ฆ‰ ViewController์˜ ์ธ์Šคํ„ด์Šค ์ž์‹ ์„ ์œ„์ž„์ž(delegate)๋กœ ์„ค์ •ํ•˜๊ณ , didSelectRowAt ๋ฉ”์†Œ๋“œ์— ์…€์„ ํƒญํ–ˆ์„ ๋•Œ ์–ด๋–ค ํ–‰๋™์„ ํ• ์ง€๋ฅผ ์ •์˜ํ•œ๋‹ค.

 

ํ…Œ์ด๋ธ”๋ทฐ๊ฐ€ ์•Œ์•„์„œ ๋‹ค ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™์€๋ฐ ์™œ ๊ตณ์ด ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์œ„์ž„์„ ํ•ด์ฃผ๋Š” ๊ฑธ๊นŒ?

 

๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ UITableView์˜ ๋‚ด๋ถ€ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์…€์ด ํƒญ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค ํ–‰๋™์„ ํ• ์ง€๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์• ํ”Œ์ด ์ˆจ๊ฒจ๋†“์€ ํ…Œ์ด๋ธ”๋ทฐ ์•ˆ์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด์—์„œ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค€ ๋’ค, ํ…Œ์ด๋ธ”๋ทฐ๊ฐ€ ๊ทธ ๊ฐ์ฒด์˜ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ค˜์•ผ ํ•œ๋‹ค.

์ด ๋•Œ ํ…Œ์ด๋ธ”๋ทฐ์™€ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๋ฐฉ์‹์ด Delegate Pattern์ธ ๊ฒƒ์ด๋‹ค.

 

Delegate Pattern์„ ํ†ตํ•ด ๊ตฌํ˜„ํ•œ ๋ฐฉ์‹์„ ๊ฐ„๋žตํžˆ ์ƒ์ƒํ•ด๋ณธ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

// Delegate Protocol
protocol UITableViewDelegate: AnyObject {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
}

// Delegating Object
class UITableView {

    weak var delegate: UITableViewDelegate?

    func didSelectedRowAt(indexPath: IndexPath) {
        delegate?.tableView(self, didSelectRowAt: indexPath)
    }
}

// Delegate Object
class ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(indexPath)
    }
}

์ฆ‰, ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์˜ ํ•ต์‹ฌ์€ ๋‘ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ, ๋‘๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ํšจ์œจ์ ์œผ๋กœ ์†Œํ†ตํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

UI์š”์†Œ์—์„œ๋Š” ์œ„์˜ ์‚ฌ๋ก€์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ
์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๋Š” ๊ฐ์ฒด(ex. UITableView)๊ฐ€ ๊ทธ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์–ด๋–ค ํ–‰๋™์„ ํ• ์ง€๋ฅผ delegate(ex. ViewController)์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค.

 

delegate๋Š” ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋‚ฌ์„ ๋•Œ ๊ทธ ๊ฐ์ฒด๋ฅผ ๋Œ€์‹ ํ•ด์„œ ํ–‰๋™ํ•˜๋Š” ๊ฐ์ฒด์ธ ๊ฒƒ!
๊ทธ๋ž˜์„œ ์ฃผ๋กœ delegating ๊ฐ์ฒด๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” responder ๊ฐ์ฒด(UIResponder๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฐ์ฒด)๋‹ค.

 

๐Ÿ’ก ๋‘ ๊ฐ์ฒด์˜ ์†Œํ†ต์„ ์œ„ํ•œ Delegate Pattern

UI์š”์†Œ์—์„œ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์ด์šฉํ•˜๋Š” ์ด์œ ๋Š” ์šฐ๋ฆฌ๊ฐ€ UI์š”์†Œ์˜ ๋‚ด๋ถ€ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ด์•ผ๊ธฐํ–ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์• ํ”Œ์ด ์ด๋ฏธ ๊ตฌํ˜„ํ•ด๋†“์€ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์ด ์•„๋‹Œ, ์šฐ๋ฆฌ๊ฐ€ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ํ™œ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฑด ์–ด๋–ค ๊ฒฝ์šฐ์ผ๊นŒ?

์œ„์—์„œ ๋งํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์˜ ํ•ต์‹ฌ์€ ๋‘ ๊ฐ์ฒด์˜ ์†Œํ†ต์ด๋ฏ€๋กœ ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ํ™œ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋ณดํ†ต์€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์€ ๊ฐ์ฒด์™€ ๊ทธ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ ๋‘ ๊ฐ์ฒด๋ฅผ ์†Œํ†ตํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์“ฐ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

 

 

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

๋ˆ„์›Œ์žˆ๋Š”๋ฐ ๊ฐ‘์ž๊ธฐ ์•„์ด์Šคํฌ๋ฆผ์ด ๋จน๊ณ ์‹ถ์–ด์กŒ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‚˜๊ฐ€๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ๊ท€์ฐฎ์•„์„œ ๋™์ƒ์—๊ฒŒ ์•„์ด์Šคํฌ๋ฆผ์„ ์‚ฌ์˜ค๋ผ๊ณ  ์‹œํ‚ค๋ ค๊ณ  ํ•œ๋‹ค.

class Me {
    weak var delegate: Brother?

    func ์˜ฌ๋•Œ๋ฉ”๋กœ๋‚˜() {
        delegate?.buyIcecream()
    }
}

class Brother {
    let me = Me()

		init() {
        me.delegate = self
    }

    func buyIcecream() {
        print("๋ฉ”๋กœ๋‚˜๋ฅผ ์ƒ€๋‹ค")
    }
}

 

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์— ๋Œ€ํ•œ ๋งŽ์€ ์˜ˆ์ œ ์ฝ”๋“œ๋“ค์„ ๋ณด๋ฉด ํ”„๋กœํ† ์ฝœ์„ ๊ผญ ๊ตฌํ˜„ํ•ด๋†“์ง€๋งŒ, ์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ํ”„๋กœํ† ์ฝœ ์—†์ด๋„ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
์œ„์ž„ํ•˜๋Š” ๊ฐ์ฒด์™€ ์œ„์ž„๋ฐ›๋Š” ๊ฐ์ฒด, ์œ„์ž„ํ•  ํ–‰๋™๋งŒ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

 

Me๋Š” ์•„์ด์Šคํฌ๋ฆผ์„ ๋จน๊ณ  ์‹ถ๋‹ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์‚ฌ๋Ÿฌ ๊ฐ€๊ธฐ ์‹ซ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๊ฐ์ฒด, Brother์—๊ฒŒ ์•„์ด์Šคํฌ๋ฆผ์„ ์‚ฌ๋Š” ํ–‰์œ„๋ฅผ ์œ„์ž„ํ–ˆ๋‹ค. Me๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์˜ฌ๋•Œ๋ฉ”๋กœ๋‚˜๋ฅผ ์‹คํ–‰์‹œ์ผœ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉด, ์‹ค์งˆ์ ์œผ๋กœ๋Š” ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ์ธ Brother๊ฐ€ ๋Œ€์‹  ์ผ์„ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์˜ ๋งŽ์€ ์˜ˆ์ œ์—์„œ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

 

ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž.

 

protocol MeDelegate: AnyObject {
    func buyIcecream()
}

class Me {
    weak var delegate: Brother?

    func ์˜ฌ๋•Œ๋ฉ”๋กœ๋‚˜() {
        delegate?.buyIcecream()
    }
}

class Brother: MeDelegate {
    let me = Me()

		init() {
        me.delegate = self
    }

    func buyIcecream() {
        print("๋ฉ”๋กœ๋‚˜๋ฅผ ์ƒ€๋‹ค")
    }
}

class Father: MeDelegate {
    let me = Me()

		init() {
        me.delegate = self
    }

    func buyIcecream() {
        print("๋ฉ”๋กœ๋‚˜๋ฅผ ์ƒ€๋‹ค")
    }
}

๋‚˜๋Š” ์ด์ œ ๋‚จ๋™์ƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์•„๋น ์—๊ฒŒ๋„ ์•„์ด์Šคํฌ๋ฆผ์„ ์‚ฌ์˜ค๋ผ๊ณ  ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

MeProtocol์„ ๋งŒ๋“ค์–ด๋†“์œผ๋ฉด Me๋Š” MeProtocol์„ ์ฑ„ํƒํ•œ ๋ˆ„๊ตฌ์—๊ฒŒ๋“  ์•„์ด์Šคํฌ๋ฆผ์„ ์‚ฌ๋Š” ํ–‰์œ„๋ฅผ ์œ„์ž„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋ฉด, ํ›จ์”ฌ ๋” ์œ ์—ฐํ•˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ’ก ์‹ค์ œ๋กœ ์•ฑ์—์„œ ์ž‘๋™๋ฐฉ์‹

์ข€ ๋” ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ• ๋งŒํ•œ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

 

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํ”ํ•œ ๊ฒฝ์šฐ๋Š” ๋‘ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋“ฑ์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์€ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์™€ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผํ•˜๋Š” ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒฝ์šฐ, ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœํ•„ ์ˆ˜์ •์ฐฝ์—์„œ ์ด๋ฆ„, ์ „ํ™”๋ฒˆํ˜ธ, ์ฃผ์†Œ ๋“ฑ์„ ์ž…๋ ฅํ•˜๊ณ  ํ™•์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ด์ „ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ”์„ ๋•Œ ์ž…๋ ฅ๋ฐ›์€ ์ •๋ณด๋ฅผ ์ด์ „ ํ™”๋ฉด์œผ๋กœ ์ „๋‹ฌํ•ด ๋ณด์—ฌ์ค˜์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋“ค์„ ๋งํ•œ๋‹ค.

 

์ข€ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋œฌ ๋ชจ๋‹ฌ์—์„œ ์–ด๋–ค ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋Š๋ƒ์— ๋”ฐ๋ผ ๊ฐ•์•„์ง€๋‚˜ ๊ณ ์–‘์ด ์ด๋ฏธ์ง€ ๊ทธ๋ฆผ์ด ๋‚˜์˜ค๋„๋ก ํ•˜๋Š” ์•ฑ์„ ์ƒ๊ฐํ•ด๋ณด์ž.

์œ„ ์•ฑ์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

class FirstViewController: UIViewController, SecondViewControllerDelegate {
    @IBOutlet weak var presentButton: UIButton!
    @IBOutlet weak var animalImageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func presentButtonTapped(_ sender: Any) {
        let secondViewController = storyboard?.instantiateViewController(
            withIdentifier: "SecondViewController"
        ) as! SecondViewController
        secondViewController.delegate = self
        self.present(secondViewController, animated: true)
    }
    
    func showImage(of animal: String) {
        presentButton.isHidden = true
        animalImageView.image = UIImage(named: animal)
    }
}

protocol SecondViewControllerDelegate: AnyObject {
    func showImage(of animal: String)
}

class SecondViewController: UIViewController {
    weak var delegate: SecondViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func dogButtonTapped(_ sender: Any) {
        delegate?.showImage(of: "dog")
        self.dismiss(animated: true)
    }
    @IBAction func catButtonTapped(_ sender: Any) {
        delegate?.showImage(of: "cat")
        self.dismiss(animated: true)
    }
}

FirstViewController๋Š” SecondViewDelegate ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•ด SecondViewController์˜ ์œ„์ž„์ž๊ฐ€ ๋˜์—ˆ๋‹ค.

 

SecondViewController๊ฐ€ ๊ฐ•์•„์ง€ ๋˜๋Š” ๊ณ ์–‘์ด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์œผ๋ฉด delegate์—๊ฒŒ ๋ˆŒ๋Ÿฌ์ง„ ๋ฒ„ํŠผ์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ณด์—ฌ๋‹ฌ๋ผ๊ณ  delegate์˜ showImage(of:)๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.


delegate์ธ FirstViewController๋Š” ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ํ†ตํ•ด ์–ด๋–ค ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ๋Š”์ง€์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ํ•ด๋‹นํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋‹ค.

 

 

๐Ÿ’ก ์ฃผ์˜ํ•  ์ : Strong Reference Cycle
์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด delegate ํ”„๋กœํผํ‹ฐ๋ฅผ ์ •์˜ํ•  ๋•Œ weak๋กœ ์„ ์–ธํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด ์—ฐ๊ฒฐํ•  ๊ฒฝ์šฐ, Strong Reference Cycle์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.
delegating ๊ฐ์ฒด๋Š” delegate ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ์ƒ๋Œ€ ๊ฐ์ฒด๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ณ , delegate ๊ฐ์ฒด ์—ญ์‹œ delegating ๊ฐ์ฒด๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Strong Reference Cycle์ด ์ƒ๊ธฐ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
delegate ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ์–ธํ•  ๋•Œ๋Š” weak๋กœ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ delegate๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋ณ„๋„์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋“ฑ์˜ ๋ฐฉ์‹์œผ๋กœ Strong Reference Cycle์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‘๊ฐœ์˜ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ ์‚ฌ์ด์— ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์œ„ํ•ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ, delegating ๊ฐ์ฒด๋Š” delegateํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ์ƒ๋Œ€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ณ , delegate ๊ฐ์ฒด๋„ ํ”„๋กœํผํ‹ฐ ๋“ฑ์„ ํ†ตํ•ด delegating ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด ์„œ๋กœ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค.์ด๋ ‡๊ฒŒ ๋˜๋ฉด ํ•˜๋‚˜์˜ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํŒ๋ผ์„œ ์‚ฌ๋ผ์ง„๋‹ค๊ณ  ํ•ด๋„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜์ง€ ์•Š์•„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ƒ๊ธด๋‹ค.