๐ŸŽ iOS/๋””์ž์ธํŒจํ„ด

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด

JerryiOS 2023. 3. 22. 19:42

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด

๊ฐ์ฒด๊ฐ€ ์ž์‹ ์˜ ์ฑ…์ž„์„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์œ„์ž„(Delegate)ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ์†Œํ†ตํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

์˜ˆ์ œ

import UIKit

protocol ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ {
    func ํ•จ์ˆ˜A()
}

class ClassA {

    var delegate: ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ?

    func A์˜ํ•จ์ˆ˜() {
        delegate?.ํ•จ์ˆ˜A()
    }

}


class ClassB: ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ {

    // ClassB๋Š” ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์ฑ„ํƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜A()๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.
    func ํ•จ์ˆ˜A() {
        print("ํ•จ์ˆ˜A๊ฐ€ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
    }

}

let classA = ClassA()
let classB = ClassB()

classA.delegate = classB

classA.A์˜ํ•จ์ˆ˜()    // ํ•จ์ˆ˜A๊ฐ€ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ์—์„œ ClassA๋Š” ๋‚ด๋ถ€์—์„œ delegate๋ผ๋Š” ์†์„ฑ์„ ๊ฐ–๋Š”๋‹ค.

delegate์˜ ํƒ€์ž…์€ '๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ' ๋ผ๋Š” ํ”„๋กœํ† ์ฝœ๋กœ ์ง€์ •๋˜์–ด์žˆ๋‹ค.

ํ•˜๋‹จ ๋ถ€๋ถ„์—์„œ ClassA์˜ delegate๋ฅผ ClassB์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ด์€ ๋ณ€์ˆ˜๋กœ ์ง€์ •ํ•œ ๋‹ค์Œ,

ClassA์˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ๋”๋‹ˆ ClassB์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์—ˆ๋‹ค.

 

ClassA์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋”๋‹ˆ ClassB์—์„œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ๊ฒƒ์ด๋‹ค.

 

์ด๋ ‡๊ฒŒ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์ด์šฉํ•ด์„œ ๋‘ ๊ฐ์ฒด๊ฐ€ ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

 

์•ฑ์„ ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด ์ด๋ ‡๊ฒŒ ClassB์˜ ํ•จ์ˆ˜๋ฅผ ClassA์—์„œ ์‹คํ–‰ํ•ด์•ผํ•  ๊ฒฝ์šฐ๋“ค์ด ์ข…์ข… ์žˆ๋‹ค.

๋˜๋Š” ClassA์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ClassB, ClassC, ClassD์˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œ์ผœ์•ผ ํ•  ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

 

์ด๋Ÿฐ ๊ฒฝ์šฐ์— ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ ์šฉํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์ฃผ์˜ํ•ด์•ผํ•  ๋ถ€๋ถ„

๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์„ ๊ฒฝ์šฐ Strong Reference Cycle์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

weak var delegate: SomeDelegate? ์ด๋Ÿฐ์‹์˜ ์„ ์–ธ์„ ํ†ตํ•ด ๊ฐ•ํ•œ์ฐธ์กฐ์‹ธ์ดํด ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ทผ๋ฐ ์œ„ ์ฝ”๋“œ์—์„œ weak var delegate: ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ? ์ด๋ ‡๊ฒŒ ์„ ์–ธํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

'weak' must not be applied to non-class-bound 'MyDelegate'; consider adding a protocol conformance that has a class bound

 

ํ”„๋กœํ† ์ฝœ์€ ํด๋ž˜์Šค, ๊ตฌ์กฐ์ฒด, ์—ด๊ฑฐํ˜•์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์œ„์—์„œ ์„ ์–ธํ•œ ํ”„๋กœํ† ์ฝœ์€ ํด๋ž˜์Šค, ๊ตฌ์กฐ์ฒด, ์—ด๊ฑฐํ˜• ์–ด๋””์„œ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— reference count ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” unowned, weak ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด

protocol ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ: AnyObject {
    func ํ•จ์ˆ˜A()
}

class ClassA {

    weak var delegate: ๋ญ”๊ฐ€์‹œํ‚ค๋Š”๋ธ๋ฆฌ๊ฒŒ์ดํŠธ?

    func A์˜ํ•จ์ˆ˜() {
        delegate?.ํ•จ์ˆ˜A()
    }

}

AnyObject๋ฅผ ์ฑ„ํƒํ•ด์ฃผ๋ฉด ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค. (swift 4๋ฒ„์ „ ๋ฏธ๋งŒ์€ class๋ฅผ ์ฑ„ํƒํ•ด์ฃผ๋ฉด ๋œ๋‹ค.)

weak ํ‚ค์›Œ๋“œ๋Š” ์ฐธ์กฐ ์œ ํ˜•์— ๋Œ€ํ•ด์„œ๋งŒ ์ •์˜๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’ ์œ ํ˜•์ธ ๊ตฌ์กฐ์ฒด, ์—ด๊ฑฐํ˜•์—์„œ๋Š” ์ •์˜๋  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ˜์‘ํ˜•