๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • Dev Blog
iOS/Swift

[Swift] Objective-C

by ์œ ์ง„์˜ 2024. 10. 28.

 

@objc๋Š” ์–ธ์ œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

@objc ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋Š” Swift ์ฝ”๋“œ๊ฐ€ Objective-C ๊ธฐ๋ฐ˜ API์—์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ UIKit์—์„œ Target-Action ํŒจํ„ด์˜ #selector์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ์— ๋ถ™ํ˜€์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ, KVC์—์„œ ์‚ฌ์šฉ๋˜๊ณ  dynamic ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ KVO๋ฅผ ํ™œ์šฉํ•  ๋•Œ์—๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. 

 

๐Ÿ“Œ Target-Action ํŒจํ„ด

 

Target-Action ํŒจํ„ด์€ Apple์˜ UI ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์‚ฌ์šฉ๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ๋ฏธ๋ฆฌ ์ง€์ •๋œ ๊ฐ์ฒด(ํƒ€๊ฒŸ)์˜ ๋ฉ”์†Œ๋“œ(์•ก์…˜)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ด๋ฒคํŠธ์˜ ๋ฐœ์ƒ๊ณผ ๊ทธ์— ๋Œ€ํ•œ ๋ฐ˜์‘์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.

 

let button = UIButton()

button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

@objc func buttonTapped() {
	print("Action!")
}

 

 

 

๐Ÿ“Œ Selector

๋”๋ณด๊ธฐ

Objective-C๋Š” Message Dispatch ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋Ÿฐํƒ€์ž„์— ํ˜ธ์ถœ๋  ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๋Š”๋ฐ, ์ด๋•Œ ํ˜ธ์ถœํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์‹๋ณ„ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด Selector์ž…๋‹ˆ๋‹ค. UIKit์€ Objective-C ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค ๋ณด๋‹ˆ Objective-C ๊ธฐ๋ฐ˜ API๋“ค์ด ์กด์žฌํ•˜์—ฌ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์œ„ํ•œ Selector๊ฐ€ Swift์—๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

Swift 2 ์‹œ์ ˆ Selector

์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ Selector(NSStringFromSelector)๋ฅผ ์ง€์›ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Swift 2 ์‹œ์ ˆ ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ Selector๋ฅผ ํ™œ์šฉํ•˜๋Š” ์ฝ”๋“œ

Swift 3 ์ดํ›„ Selector

๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ Selector์˜ ๋ฌธ์ œ์ ์€ ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์˜คํƒ€์ผ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์—๋Ÿฌ๋ฅผ ์žก์•„์ฃผ์ง€ ๋ชปํ•ด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, #selector() ํ‚ค์›Œ๋“œ๋กœ ์ปดํŒŒ์ผ ์‹œ์— ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

@objc์™€ dynamic์˜ ์ฐจ์ด์ ์ด ๋ฌด์—‡์ธ๊ฐ€์š”?

@objc๋Š” Swift ์ฝ”๋“œ๊ฐ€ Objective-C ๋Ÿฐํƒ€์ž„์—์„œ ์ธ์‹๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์ž…๋‹ˆ๋‹ค. ์ด ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Swift ์ฝ”๋“œ์˜ ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ์†์„ฑ ๋“ฑ์„ Objective-C ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ Selector ๊ฐ™์€ Objective-C ๋Ÿฐํƒ€์ž„ ๊ธฐ๋Šฅ(Message Dispatch)์„ ์ด์šฉํ•ด์•ผ ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, Objective-C ๋Ÿฐํƒ€์ž„ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ์—๋Š” Swift์˜ Static Dispatch๋‚˜ Table Dispatch ๋ฐฉ์‹์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

 

dynamic ํ‚ค์›Œ๋“œ๋Š” Swift3 ๊นŒ์ง€๋Š” dynamic ํ‚ค์›Œ๋“œ๋งŒ ์ ์–ด๋„ ์ž๋™์œผ๋กœ @objc ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ํฌํ•จํ–ˆ์œผ๋‚˜ Swift4๋ถ€ํ„ฐ @objc dynamic ๊ฐ™์ด ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ‚ค์›Œ๋“œ๋Š” @objc ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๊ธฐ๋Šฅ์— ๋”ํ•ด, Swift ์š”์†Œ๊ฐ€ Objective-C์˜ Message Dispatch ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋Ÿฐํƒ€์ž„์— ๋ฉ”์„œ๋“œ๋ฅผ ๊ต์ฒดํ•˜๋Š” Method Swizzling์ด๋‚˜ KVO์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

๐Ÿ“Œ Method Swizzling

๋”๋ณด๊ธฐ

Method Swizzling์ด๋ž€ ๋Ÿฐํƒ€์ž„์— ๋ฉ”์„œ๋“œ๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Swift์—์„œ๋Š” ๋Ÿฐํƒ€์ž„์— ๋ฉ”์„œ๋“œ๋ฅผ ๊ต์ฒดํ•  ์ˆœ ์—†์–ด ๊ต์ฒด๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์— Objectiv-C ๋Ÿฐํƒ€์ž„ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ๊ต์ฒด๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์•„๋ž˜ ๋งํฌ๋กœ ๋Œ€์ฒดํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Swift ) Method Swizzling

์•ˆ๋…•ํ•˜์„ธ์š” :) Zedd์ž…๋‹ˆ๋‹ค.๋ถ„๋ช…..์ €๋ฒˆ๊ธ€์—์„œ...์ด์ œ..๋ถ€์ง€๋Ÿฐํžˆ ๊ณต๋ถ€ํ•œ๋‹ค๊ณ  ๊ทธ๋žฌ๋Š”๋ฐ...๋งค์ผ๋งค์ผ ๊ณต๋ถ€๋Š” ํ•˜๊ณ ์žˆ์ง€๋งŒ ๊ธ€ ์“ธ ์‹œ๊ฐ„์ด ์—†์Šต๋‹ˆ๋‹ค.ใ…œใ…œใ…œ ์•”ํŠผ ์˜ค๋Š˜์€ Method Swizzling์ด๋ผ๋Š”๊ฑธ ๋“ค์–ด์„œ ์ด๊ฑธ

zeddios.tistory.com

 

 

KVC๋ž€?

KVC๋ž€ Key-Value Coding์˜ ์•ฝ์ž๋กœ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— '. ์—ฐ์‚ฐ์ž'๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ”„๋กœํผํ‹ฐ๋ช…์„ ๋ฌธ์ž์—ด ํ‚ค๋กœ ํ•˜์—ฌ ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. Objective-C์˜ ์œ ์‚ฐ์œผ๋กœ์„œ Swift์—์„œ @objc ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

KVC๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ์ ์—๋Š” ์–ด๋–ค ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์€์ง€ ์ •ํ•˜์ง€ ์•Š๊ณ  ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘์— ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๋“ฑ ์กฐ๊ธˆ ๋” ๋™์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

 

 

Swift 2 ์‹œ์ ˆ Selector์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Key๊ฐ€ ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ ์˜คํƒ€๋‚˜ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ์•„๋‹Œ ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์ปดํŒŒ์ผ ํƒ€์ž„์— ์•ˆ์ „์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” Swift์‹ KVC์ธ KeyPath๊ฐ€ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์„ค๋ช…์€ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.

 

Key-Value Coding(KVC) / KeyPath in Swift

์•ˆ๋…•ํ•˜์„ธ์š” :) Zedd์ž…๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ KVC์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. # KVC - Key-Value Coding ์˜ ์•ฝ์ž - ๊ฐ์ฒด์˜ ๊ฐ’์„ ์ง์ ‘ ๊ฐ€์ ธ์˜ค์ง€์•Š๊ณ , Key ๋˜๋Š” KeyPath ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ„์ ‘์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ˆ˜์ •

zeddios.tistory.com

 

 

KVO๋ž€?

KVO๋ž€ Key-Value Observing์˜ ์•ฝ์ž๋กœ Objective-C ๋Ÿฐํƒ€์ž„์„ ํ™œ์šฉํ•˜์—ฌ ๊ฐ์ฒด์˜ ํŠน์ • ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€ํ™”๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. NSObject๋ฅผ ์ƒ์†ํ•œ ๊ฐ์ฒด์˜ @objc dynamic ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™ํžŒ ํ”„๋กœํผํ‹ฐ์—ฌ์•ผ KVO๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์‚ฌ์šฉ ์˜ˆ์‹œ

๋”๋ณด๊ธฐ

new, old ์˜ต์…˜ ์‚ฌ์šฉ

import Foundation

class Person: NSObject {
    @objc dynamic var name: String
    
    init(name: String) {
        self.name = name
    }
}

var jinyoo = Person(name: "jinyoo")

jinyoo.observe(\.name, options: [.new, .old]) { (object, change) in
    print(object.name)
    print(change.oldValue, change.newValue)
}

jinyoo.name = "Jinyoo"

// "Jinyoo"
// Optional("jinyoo") Optional("Jinyoo")

 

initial ์˜ต์…˜ ์‚ฌ์šฉ -> ์ดˆ๊ธฐํ™” ๊ณผ์ •๋„ ๋ณ€ํ™”๋กœ ์ธ์ง€

var jinyoo = Person(name: "jinyoo")

jinyoo.observe(\.name, options: [.new, .old, .initial]) { (object, change) in
    print(object.name)
    print(change.oldValue, change.newValue)
}

jinyoo.name = "Jinyoo"

// jinyoo
// nil Optional("jinyoo")
// Jinyoo
// Optional("jinyoo") Optional("Jinyoo")

 

prior ์˜ต์…˜ -> ๋ณ€ํ™” ์ด์ „๊ณผ ๋ณ€ํ™” ์ดํ›„ ์ƒํƒœ์— ๋ชจ๋‘ ํ˜ธ์ถœ 

var jinyoo = Person(name: "jinyoo")

jinyoo.observe(\.name, options: [.new, .old, .prior]) { (object, change) in
    print(object.name)
    print(change.oldValue, change.newValue)
}

jinyoo.name = "Jinyoo"

//jinyoo
//Optional("jinyoo") nil
//Jinyoo
//Optional("jinyoo") Optional("Jinyoo")

 

๐Ÿ’ก KVO, ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋ฒ„, @Published, NotificationCenter ๋น„๊ต (์˜ต์ €๋น™์„ ํ™œ์šฉํ•œ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ํŒจํ„ด๋“ค์˜ ๋น„๊ต)

KVO
• Objective-C ๋Ÿฐํƒ€์ž„ ์‚ฌ์šฉ
• ๊ฐ์ฒด ์™ธ๋ถ€์—์„œ ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋น™ ๊ด€๋ จ ์ฝ”๋“œ ์ž‘์„ฑ
• ํ”„๋กœํผํ‹ฐ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ ์ฝ”๋“œ๊ฐ€ ์ฆ‰์‹œ ์‹คํ–‰(๋™๊ธฐ์ )
• ์ดˆ๊ธฐํ™”์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜ ์กด์žฌ

 

ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋ฒ„
• ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋น™ ๊ด€๋ จ ์ฝ”๋“œ ์ž‘์„ฑ
• ํ”„๋กœํผํ‹ฐ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ ์ฝ”๋“œ๊ฐ€ ์ฆ‰์‹œ ์‹คํ–‰(๋™๊ธฐ์ )
• ์ดˆ๊ธฐํ™”์— ๋Œ€ํ•œ ์•Œ๋ฆผ์€ ๋ฐ›์ง€ ๋ชปํ•จ

 

Combine์˜ @Published ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ
• ๊ฐ์ฒด ์™ธ๋ถ€์—์„œ ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋น™ ๊ด€๋ จ ์ฝ”๋“œ ์ž‘์„ฑ ๊ฐ€๋Šฅ
• receive(on:) ์˜คํผ๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ ์‹œ ์ฆ‰์‹œ ์‹คํ–‰๋˜์ง€ ์•Š์Œ(๋น„๋™๊ธฐ์ )
• ์ดˆ๊ธฐํ™”์— ๋Œ€ํ•œ ์•Œ๋ฆผ์ด ๋””ํดํŠธ (dropFirst ์˜คํผ๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ ์‹œ ์ดˆ๊ธฐํ™”์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์Œ)

 

๐Ÿ“Œ receive(on:) ์˜คํผ๋ ˆ์ดํ„ฐ์˜ ๋น„๋™๊ธฐ์  ์‹คํ–‰์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ

๋”๋ณด๊ธฐ
import Foundation
import Combine

class A {
    @Published var name: String
    
    init(name: String) { self.name = name }
}

class B {
    var name: String {
        didSet {
            print("B")
        }
    }

    init(name: String) { self.name = name }
}

class Observing {
    var a: A
    var b: B
    var cancellables = Set<AnyCancellable>()

    init(a: A, b: B) {
        self.a = a
        self.b = b
        self.useCombine()
    }
    
    private func useCombine() {
        self.a.$name
            .dropFirst()
            .receive(on: RunLoop.main)
            .sink { new in
                print("A")
            }
            .store(in: &cancellables)
    }
}

var a = A(name: "jinyoo") // @Published ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ ์‚ฌ์šฉ ๊ฐ์ฒด
var b = B(name: "jinyoo") // ํ”„๋กœํผํ‹ฐ ์˜ต์ €๋ฒ„ ์‚ฌ์šฉ ๊ฐ์ฒด
var obs = Observing(a: a, b: b)

obs.a.name = "Jinyoo"
obs.b.name = "Jinyoo"

// B
// A

 

๐Ÿ“Œ receive(on:) ์˜คํผ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด?

๋”๋ณด๊ธฐ

receive(on:) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, Combine์˜ @Published ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€ํ™” ๊ฐ์ง€๋‚˜ ๋‹ค๋ฅธ Combine ์ŠคํŠธ๋ฆผ์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋Š” receive(on:)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์ •ํ•œ ์Šค์ผ€์ค„๋Ÿฌ์— ์˜์กดํ•˜์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์–ด๋–ค ์Šค์ผ€์ค„๋Ÿฌ์—์„œ ์‹คํ–‰๋ ์ง€๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐœํ–‰(publish)ํ•˜๋Š” ์ชฝ์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋”ฐ๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ์˜ ์ฃผ์š” ์ฐจ์ด์ ์„ ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.


๋””ํดํŠธ ๋™์ž‘: receive(on:) ์—†์ด, Combine์˜ ์˜คํผ๋ ˆ์ดํ„ฐ๋“ค์€ upstream์—์„œ ๋ฐ›์€ ์ž‘์—…์„ ๊ทธ๋“ค์ด ๋ฐ›์€ ๊ฐ™์€ ์Šค๋ ˆ๋“œ ๋˜๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์†Œ์Šค ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด ๋ฐœํ–‰๋˜๋Š” ์Šค๋ ˆ๋“œ์™€ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ์—์„œ ๊ตฌ๋…์ž์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฆ‰๊ฐ์  ์‹คํ–‰: ํŠน๋ณ„ํ•œ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๊ฐ์ง€ ํ›„ ํ•ด๋‹น ๋ณ€ํ™”๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํด๋กœ์ €๋Š” ๊ฐ€๋Šฅํ•œ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Š” ์›๋ž˜์˜ ์ž‘์—… ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€๋ฒผ์šด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์–ด์•ผ ๊ฐ€๋Šฅํ•œ ์ผ์ž…๋‹ˆ๋‹ค.

 

๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€์˜ ๊ด€๊ณ„: UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ž‘์—…๊ณผ ๊ฐ™์ด ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ์ผ ๊ฒฝ์šฐ, receive(on:)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐœํ–‰(publish)๋˜๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹ ๋•Œ UI ์—…๋ฐ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ๊ณณ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์€ ๋™์ž‘์ด๋‚˜ ์•ฑ ํฌ๋ž˜์‹œ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

NotificationCenter
• ๋‹ค๋ฅธ ๊ฒƒ๋“ค๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ”„๋กœํผํ‹ฐ ๋ณ€ํ™”๋ณด๋‹ค ๊ฐ์ฒด ๊ฐ„ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๋” ์ค‘์ ์„ ๋‘” ์˜ต์ €๋น™์— ๊ฐ€๊นŒ์›€
•  ๋”ฐ๋ผ์„œ, ๋‹ค๋ฅธ ์„ธ ๊ฐœ๋ณด๋‹ค Delegate ํŒจํ„ด๊ณผ ๋น„๊ตํ•ด์„œ ๊ณต๋ถ€ํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ๊ณผ์ 
 

Delegation, Notification, ๊ทธ๋ฆฌ๊ณ  KVO

์–ธ์ œ, ์–ด๋””์„œ ์จ์•ผํ• ๊นŒ?

medium.com

 

๋Œ“๊ธ€