iOS ์•ฑ ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜/TIL

7์ฃผ์ฐจ_4์ผ์ฐจ_์•ฑ ๊ฐœ๋ฐœ ์ˆ™๋ จ_๊ฐœ์ธ๊ณต๋ถ€_TIL

yeggrrr๐Ÿผ 2024. 4. 18. 20:16


<TIL>

์˜ค๋Š˜์€ ๊ณผ์ œ ์ œ์ถœํ•  ๋•Œ ํ•จ๊ป˜ ์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ๊ธฐ์ˆ  ์งˆ๋ฌธ๋“ค ์ •๋ฆฌํ•ด์„œ ์ œ์ถœํ–ˆ๋‹ค.
(๊ฐœ์ธ๊ณผ์ œ ๋!! - ์œ„์‹œ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ์— ๋Œ€ํ•ด์„œ๋Š” ์ถ”ํ›„์— ์ •๋ฆฌ ์˜ˆ์ •)

์ดํ›„ ์•„๋ž˜ 7๊ฐ€์ง€์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ๋‹ค.

1.  Class ์™€ Struct
2. override์™€ overload / overriding๊ณผ overloading
3. mutating ํ‚ค์›Œ๋“œ
4. final
5. Escaping Closure
6. protocol
7. Eqautable

์–ด๋””์„ ๊ฐ€ ๋“ค์—ˆ๊ฑฐ๋‚˜ ์•Œ๊ณ ๋Š” ์žˆ์ง€๋งŒ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ ๋‚ด์šฉ๋“ค
ํ˜น์€ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ฒ˜์Œ ๋ณด๋Š” ๊ฒƒ๋“ค์ด๋‹ค.
์ด ๋ฐ–์—๋„ ๋‹ค์–‘ํ•˜์ง€๋งŒ ์˜ค๋Š˜์€ ์œ„์— 7๊ฐ€์ง€์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.



Class / Struct

Class์™€ Struct์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž!


Class์™€ Struct๋Š” ๊ฐ์ œ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OPP)๋ฅผ ์œ„ํ•œ ํ•„์ˆ˜์š”์†Œ์ด๊ณ ,
์ฝ”๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

<Class>

โ‘  ์ฐธ์กฐ ํƒ€์ž…(Reference Type)์ด๋‹ค.

-> ํ•˜๋‚˜์˜ ๋ณต์ œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ํ• ๋‹นํ•œ ์ธ์Šคํ„ด์Šค๋“ค์ด ํ•จ๊ป˜ ๊ณต์œ 

โ‘ก ์ƒ์†์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

โ‘ข ํ”„๋กœํ† ์ฝœ(Protocol) ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

โ‘ฃ extension์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

โ‘ค subscript ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
(subscript:
์ฝœ๋ ‰์…˜, ๋ฆฌ์ŠคํŠธ ๊ทธ๋ฆฌ๊ณ  ์‹œํ€€์Šค ๋“ฑ์— ๋ณ„๋„์˜ ๋ฉ”์†Œ๋“œ ์—†์ด index๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ.
๋˜ํ•œ ํด๋ž˜์Šค, ๊ตฌ์กฐ์ฒด, ์—ด๊ฑฐํ˜•์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ž…๋ ฅ ๊ฐ’์˜ ํƒ€์ž…์— ๋”ฐ๋ผ ์˜ค๋ฒ„๋กœ๋”ฉ๋„ ๊ฐ€๋Šฅํ•จ.)

โ‘ฅ ํƒ€์ž…์บ์ŠคํŒ…(Type Casting)์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
- as

โ‘ฆ ๋ฉ”๋ชจ๋ฆฌ๋Š” heap ์˜์—ญ์— ์ €์žฅ๋œ๋‹ค.

โ‘ง ===๋ฅผ ํ†ตํ•ด ๋‘ ์ฐธ์กฐ ํƒ€์ž…์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
(๋‘ ์ธ์Šคํ„ด์Šค์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ™์€์ง€ ๋น„๊ต)

<Struct>

โ‘  ๊ฐ’ ํƒ€์ž…(Value Type)์ด๋‹ค.
-> ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๋ณต์ œํ•˜์—ฌ ํ• ๋‹นํ•œ ์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ์œ ๋‹ˆํฌํ•˜๊ฒŒ ๊ฐ€์ง

โ‘ก ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

โ‘ข ํ”„๋กœํ† ์ฝœ(Protocol) ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

โ‘ฃ ๋ฉ”๋ชจ๋ฆฌ๋Š” Stack ์˜์—ญ์— ์ €์žฅ๋œ๋‹ค.

โ‘ค ==๋ฅผ ํ†ตํ•ด ๋‘ ๊ฐ’ ํƒ€์ž…์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
(๋‘ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ๋น„๊ต)


class Person {
    let name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let yeggrrr = Person(name: "YeBao", age: 27) // ์ธ์Šคํ„ด์Šค let
var keen = Person(name: "HyeBao", age: 29)

์ธ์Šคํ„ด์Šค๋กœ let์ด ์„ ์–ธ๋˜์–ด ์žˆ์–ด๋„ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค!

yeggrrr.name = "YeBao2" // error: cannot assign to property -> let ํ”„๋กœํผํ‹ฐ
keen.name = "keen2" // error: cannot assign to property -> let ํ”„๋กœํผํ‹ฐ

yeggrrr.age = 20
keen.age = 22

struct Car {
    let color: String
    var owner: String
}

let newCar = Car(color: "Black", owner: "yeggrrr")
var oldCar = Car(color: "White", owner: "keen")

์ธ์Šคํ„ด์Šค๋กœ let์ด ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฉด ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค!

newCar.owner = "keen" // error: Cannot assign to property: 'newCar' is a 'let' constant -> let ์ธ์Šคํ„ด์Šค
newCar.color = "Red" // Cannot assign to property: 'color' is a 'let' constant -> let ํ”„๋กœํผํ‹ฐ

oldCar.owner = "yeggrrr"
oldCar.color = "Blue" // Cannot assign to property: 'color' is a 'let' constant -> let ํ”„๋กœํผํ‹ฐ

class & struct ๋‘˜ ๋‹ค ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ๊ฐ€ let์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฉด ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค!

 

 


override์™€ overload /
overriding๊ณผ overloading

- override: ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ
- overload: ์ธ์ž์˜ ๊ฐฏ์ˆ˜๊ฐ€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ

- overriding:
-> ์Šˆํผํด๋ž˜์Šค์—์„œ ์ƒ์†ํ•œ ๋ฉ”์„œ๋“œ, ํ”„๋กœํผํ‹ฐ, ์„œ๋ธŒ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„œ๋ธŒ ํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ
-> ์ƒ์† ๊ด€๊ณ„์—์„œ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํ•จ์ˆ˜ ๋‚ด์šฉ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ ์ž์‹ ํด๋ž˜์Šค์—์„œ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ.
(์ž์‹ ํด๋ž˜์Šค์—์„œ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„, ๋งค๊ฐœ๋ณ€์ˆ˜, ๋ฆฌํ„ด ๊ฐ’์ด ๋ชจ๋‘ ๊ฐ™์•„์•ผ ํ•จ)

- overloading
-> ๋ฆฌํ„ดํƒ€์ž…, ์ธ์ž์˜ ๊ฐฏ์ˆ˜, ์ธ์žํƒ€์ž…์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ.
-> ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ฉ”์†Œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค๋ฅด๊ฒŒ ์„ ์–ธ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์˜๋ฏธ.


mutating ํ‚ค์›Œ๋“œ

swfit์—์„œ ๊ตฌ์กฐ์ฒด(struct)๋Š” ๊ฐ’ ํƒ€์ž…์˜ ๋ถˆ๋ณ€ ๊ฐ์ฒด(immutable object)์ด๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ๋ฉ”์„œ๋“œ ์•ž์— mutating ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋ฉด
๊ตฌ์กฐ์ฒด(struct)๋‚˜ ์—ด๊ฑฐํ˜•(enum) ์ธ์Šคํ„ด์Šค์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

mutating ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด,
swift๋Š” ์ƒˆ๋กœ์šด ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์ฒด(struct)๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ํ• ๋‹นํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜์—ฌ
๊ธฐ์กด์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•œ๋‹ค.

mutating์„ ์“ฐ๋Š” ์ด์œ ๋Š” ๊ตฌ์กฐ์ฒด(struct)์˜ ๋ถˆ๋ณ€์„ฑ์„ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.


struct ExStruct {
    var value: Int = 0
    
    mutating func increaseValue(increment: Int) {
        self = ExStruct(value: value + increment)
    }
}


์—ฌ๊ธฐ์—์„œ ๊ตฌ์กฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ let์œผ๋กœ ์„ ์–ธํ•œ๋‹ค๋ฉด?

let constantStruct = ExStruct()
constantStruct.increaseValue(increment: 30) // error : change 'let' to 'var' to make it mutable

error๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
๊ทธ ์ด์œ ๋Š” ์ƒ์ˆ˜๋กœ ์„ ์–ธ๋œ ๊ฐ์ฒด์— ์ƒˆ๋กœ์šด ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

let์ด ์•„๋‹Œ var๋กœ ๋ฐ”๊พธ์–ด ์‹คํ–‰ํ•˜๋ฉด, ์ •์ƒ์ ์œผ๋กœ ์ž˜ ์ž‘๋™ํ•  ๊ฒƒ์ด๋‹ค.



final ํ‚ค์›Œ๋“œ

final ํ‚ค์›Œ๋“œ๋Š” ํ•ด๋‹น class, method, property๊ฐ€ ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ ,
ํ•˜์œ„ํด๋ž˜์Šค์—์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๋Š” ํ‚ค์›Œ๋“œ์ด๋‹ค.

final class ExClass {
    var exValue: Int = 0
}

class derivedExampleClass : ExClass { // ERROR: Inheritance from a final class 'ExClass'
}

์ด์ฒ˜๋Ÿผ final ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
์ด ํ‚ค์›Œ๋“œ๋Š” ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค ์•ˆ์˜ ์ผ๋ถ€ ํ•จ์ˆ˜๋ฅผ override ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.


Escaping Closure

'Escaping Closure'๋Š”
ํด๋กœ์ €๊ฐ€ ํ•จ์ˆ˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋˜์—ˆ์„ ๋•Œ, ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์ข…๋ฃŒ๋œ ํ›„ ์‹คํ–‰๋˜๋Š” ํด๋กœ์ €๋ฅผ ๋งํ•œ๋‹ค.

๋ฐ˜๋Œ€๋กœ ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ์‹คํ–‰๋˜๋Š”
'Non-Escaping Closure'๋„ ์žˆ๋‹ค.

.
.
.

(์˜ˆ์‹œ๋Š” ์ถ”ํ›„์— ์ถ”๊ฐ€ํ•  ์˜ˆ์ •)


ํ”„๋กœํ† ์ฝœ(protocol)

ํ”„๋กœํ† ์ฝœ์ด ๋ฌด์—‡์ผ๊นŒ?

ํŠน์ • ์—ญํ• ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ, ํ”„๋กœํผํ‹ฐ, ๊ธฐํƒ€ ์š”๊ตฌ์‚ฌํ•ญ ๋“ฑ์˜ ์ฒญ์‚ฌ์ง„์„ ๋งํ•œ๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด,
'๊ทœ์•ฝ, ์ง€์ผœ์•ผํ•˜๋Š” ์•ฝ์†'
์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

๋ณ€์ˆ˜, ํ•จ์ˆ˜ ๋‘˜๋‹ค ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๊ณ ,
๋ณ€์ˆ˜์—๋Š” get, set ์ค‘ ์–ด๋–ค๊ฑฐ ํ• ์ง€ ์„ ํƒํ•ด์•ผ ๋œ๋‹ค.
(๋‹จ, set์€ ํ˜ผ์ž ์žˆ์„ ์ˆ˜ ์—†์Œ. get ํ˜น์€ get set ์„ ํƒ)
(get์€ ๋ฐ›๊ธฐ๋งŒ ํ•  ์ˆ˜ ์žˆ์Œ. get set์€ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Œ.)

protocol LivingAnimal {
    var canTalk: Bool { get set }
    func canEat()
    func canSleep()
}

์ด๋ ‡๊ฒŒ ํ”„๋กœํ† ์ฝœ์„ ์ •์˜ํ•˜๊ณ ,

struct Cat: LivingAnimal {
    
}

์ด๋ ‡๊ฒŒ ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์„ ์ƒ์†๋ฐ›์œผ๋ ค๊ณ  ํ•˜๋ฉด,

์ •์˜ํ•œ ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ error ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Fix๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ๋ฉด

struct Cat: LivingAnimal {
    var canTalk: Bool
    
    func canEat() {
        
    }
    
    func canSleep() {
        
    }
}

์œ„์—์„œ ์ •์˜ํ•œ๋Œ€๋กœ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ค€๋‹ค.

์ด์ฒ˜๋Ÿผ ์ƒ์† ๋ฐ›๋Š” ํ”„๋กœํ† ์ฝœ์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.


Equatable

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๊ตฌ์กฐ์ฒด, ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋น„๊ตํ•˜๋ ค๊ณ  ==์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด,
์—๋Ÿฌ๊ฐ€ ๋œจ๊ฒŒ ๋œ๋‹ค.

์ด๋•Œ ์ด Equatable์„ ์‚ฌ์šฉํ•˜๋ฉด,
ํƒ€์ž…๋ผ๋ฆฌ ==์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ฆ‰, Equatable์€ ํƒ€์ž…๋ผ๋ฆฌ ๋น„๊ต์—ฐ์‚ฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•„์ˆ˜์ ์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ด๋‹ค!
Equatable์€ ์ค€์ˆ˜ํ•˜๊ฒŒ ๋˜๋ฉด, ==ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค!


 

Equatable | Apple Developer Documentation

A type that can be compared for value equality.

developer.apple.com

(์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ ํ™•์ธ)


class Person: Equatable {
    let name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    // lhs: left hand side / rhs: right hand side
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
        && lhs.age == rhs.age
    }
}
let a = Person(name: "bob", age: 16)
let b = Person(name: "bob", age: 16)

a == b // true
let a = Person(name: "bob", age: 8)
let b = Person(name: "bob", age: 16)

a == b // false

 

728x90