Swift
Computer Science of Swift

πŸ’› Swift

Swift ν•¨μˆ˜ ν˜•νƒœ 및 κ΄€λ ¨ μš©μ–΄

πŸ‘‰ func ν•¨μˆ˜λͺ…(μ „λ‹¬μΈμž λ ˆμ΄λΈ” λ§€κ°œλ³€μˆ˜ λ ˆμ΄λΈ”: λ§€κ°œλ³€μˆ˜ νƒ€μž…)
γ€€γ€€πŸ‘‹ func hello(to num: Int) { ~ }
γ€€γ€€πŸ‘‹ func hello(_ str: String) -> String { ~ }
πŸ‘‰ μ „λ‹¬μΈμž λ ˆμ΄λΈ” : ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ λ§€κ°œλ³€μˆ˜μ˜ 역할을 μ’€ 더 λͺ…ν™•νžˆ ν•˜λŠ” μ—­ν• , λ‹€λ₯΄κ²Œ λ ˆμ΄λΈ”μ„ 써쀌으둜써 μ˜€λ²„λ‘œλ”© κ°€λŠ₯
πŸ‘‰ λ§€κ°œλ³€μˆ˜ : ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ μ™ΈλΆ€λ‘œλΆ€ν„° μ „λ‹¬λœ κ°’μ˜ 이름, ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ „λ‹¬λœ 값을 닀루기 μœ„ν•œ μ—­ν• 
πŸ‘‰ _ : μ™€μΌλ“œ μΉ΄λ“œ νŒ¨ν„΄, λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ 없을 λ•Œ μ‚¬μš©, κ³΅λž€ λŒ€μ‹  μž…λ ₯st
πŸ‘‰ κ°€λ³€ λ§€κ°œλ³€μˆ˜ : λ§€κ°œλ³€μˆ˜λ‘œ λͺ‡ 개의 값이 λ“€μ–΄μ˜¬μ§€ λͺ¨λ₯Ό λ•Œ μ‚¬μš©ν•  수 있으며, ν•¨μˆ˜λ§ˆλ‹€ κ°€λ³€ λ§€κ°œλ³€μˆ˜λŠ” ν•˜λ‚˜λ§Œ κ°€μ§ˆ 수 있음
γ€€γ€€πŸ‘‰ νƒ€μž… 뒀에 β€¦μœΌλ‘œ λ‚˜νƒ€λƒ„
γ€€γ€€πŸ‘‹ func hello(_ num: Int, _ result: Int…) { ~ }


rawValue(μ›μ‹œκ°’)

πŸ‘‰ μ—΄κ±°ν˜•μ˜ 각 μΌ€μ΄μŠ€κ°€ 기본적으둜 κ°–κ³  μžˆλŠ” κ°’
πŸ‘‰ 각 μΌ€μ΄μŠ€λŠ” μ›μ‹œκ°’μ„ 가지고 μžˆμ§€ μ•Šμ„ 수 있음 // μ—΄κ±°ν˜•μ˜ μ΄λ¦„λ§Œ 있고 νƒ€μž…μ€ 없이 μ„ μ–Έλ˜μ–΄ μžˆλŠ” 경우
πŸ‘‰ μ •μˆ˜ν˜•μ˜ 첫번째 μΌ€μ΄μŠ€ 기본적으둜 0, ν•œ μΌ€μ΄μŠ€μ˜ μ›μ‹œκ°’μ€ 이전 μΌ€μ΄μŠ€μ˜ μ›μ‹œκ°’ + 1
πŸ‘‰ μ‹€μˆ˜ν˜•μ˜ 첫번째 μΌ€μ΄μŠ€ 기본적으둜 0, ν•œ μΌ€μ΄μŠ€μ˜ μ›μ‹œκ°’μ€ 이전 μΌ€μ΄μŠ€κ°€ μ •μˆ˜κ°’μΌ 경우 + 1, 이전 μΌ€μ΄μŠ€κ°€ μ‹€μˆ˜ν˜•μΌ 경우 μ—λŸ¬
πŸ‘‰ Stringν˜•μ˜ μ›μ‹œκ°’μ€ 기본적으둜 μžμ‹ μ˜ case μ΄λ¦„μ˜ κ°’ ν˜Ήμ€ 직접 μ§€μ •ν•œ κ°’
πŸ‘‰ Character의 μ›μžκ°’μ€ λͺ¨λ‘ 직접 μ„ μ–Έν•΄μ•Ό 함


associated Value(μ—°κ΄€κ°’)

πŸ‘‰ μ—΄κ±°ν˜•μ—μ„œ 각 μΌ€μ΄μŠ€λ“€μ€ 각자 단 ν•˜λ‚˜μ˜ μ›μ‹œκ°’λ§Œ κ°€μ§ˆ 수 있음
πŸ‘‰ μ΄λŸ¬ν•œ 단점을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ 각 μΌ€μ΄μŠ€κ°€ 상황에 따라 λ‹€λ₯Έ 값을 κ°€μ§€κ²Œ ν•˜κΈ° μœ„ν•΄μ„œ μ‚¬μš©ν•˜λŠ” κ°œλ…
πŸ‘‰ μΌ€μ΄μŠ€μ— νŠœν”Œ ν˜•νƒœλ‘œ νƒ€μž…μ„ λͺ…μ‹œν•˜μ—¬ μ‚¬μš©
γ€€γ€€πŸ‘‹ case caseName(model: String)
γ€€γ€€πŸ‘‹ case caseName(model: String, size: Int)
γ€€γ€€πŸ‘‹ let a: ENUM~ = ENUM~.caseName(model: β€œhello”, size: 10) // 직접 값을 μ§€μ •ν•˜μ—¬ μ‚¬μš©
πŸ‘‹ Link


연관값을 κ°€μ§€λŠ” μ—΄κ±°ν˜• 맀칭 πŸ”₯

πŸ‘‰ ex1) enum switch

let commute = Transportation.subway(line: 2, express: false)

switch commute { // μ—¬κΈ°μ„œ Transportation νƒ€μž… μΆ”λ‘ 
    case .subway(2): ~ // λ”°λΌμ„œ, μƒλž΅ κ°€λŠ₯
	case .car: ~
	case .bus(1): ~
	case .bus(2, "seoul", _): ~
	case .bus(3, let src, let dest): ~
    // λͺ¨λ“  λ³€μˆ˜μ˜ 바인딩 방식이 λ™μΌν•˜λ‹€λ©΄ letμ΄λ‚˜ var을 맨 μ•žμ— μ“Έ 수 있음
    case let .plain(line, station):
        print("line: \(line), station: \(station)")
    default:
        break // 각 caseμ—” breakκ°€ μƒλž΅λ˜μ–΄ 있으며, κ³΅λž€μ€ ν—ˆμš©ν•˜μ§€ μ•ŠκΈ°μ— do nothing κΈ°λŠ₯을 μœ„ν•΄μ„œλŠ” breakλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μž‘μ„±ν•΄μ•Ό 함
}

πŸ‘‰ ex2) enum if

let commute = Transportation.subway(line: 2, express: false)
if case let .subway(2, express) = commute { ~ }
// #1 let을 case뒀에 μž‘μ„±ν•¨μœΌλ‘œμ¨ μΈμžμ— let을 적지 μ•Šμ•„λ„ 됨 // if case .subway(2, let express) = commute
// #2 commuteκ°€ μ™Όμͺ½κ³Ό λ§€μΉ­λ˜λƒμ˜ 의미
// #3 .subway둜 μž‘μ„±μ΄ κ°€λŠ₯ν•œ μ΄μœ λŠ” 였λ₯Έμͺ½μœΌλ‘œλΆ€ν„° νƒ€μž…μ„ μ°Έκ³ ν•˜μ˜€κΈ° λ•Œλ¬Έ
// #4 if case let ; switchλ¬Έκ³Ό 같이 λͺ¨λ“  μΌ€μ΄μŠ€λ₯Ό μž‘μ„±ν•˜λŠ” 것이 μ•„λ‹Œ μ›ν•˜λŠ” 단 ν•˜λ‚˜μ˜ 경우만 체크할 수 μžˆλ„λ‘ ν•˜μ—¬ νŽΈν•˜κ²Œ μ‚¬μš©ν•˜λ„λ‘ ν•˜λŠ” swift 문법
// ; The Swift If-Case-Let syntax is a convenient shortcut to avoid a full switch statement when you only want to match a single case.


μ—΄κ±°ν˜• νŠΉμ§•

πŸ‘‰ enum은 μ—°μ‚° ν”„λ‘œνΌν‹°λ‚˜ λ©”μ†Œλ“œλ₯Ό 포함할 수 있으며, ν™•μž₯이 κ°€λŠ₯ν•˜κ³ , ν”„λ‘œν† μ½œμ„ λ”°λ₯΄λ„둝 μ •μ˜ν•  수 있음
γ€€γ€€πŸ‘‹ ex)

enum HTTPCode: Int {
    case OK = 200
    case NOT_MODIFY = 304
    case SERVER_ERROR = 500

    var value: String { // μ—°μ‚° ν”„λ‘œνΌν‹° (읽기 μ „μš©, get μƒλž΅)
        return "HTTP number is \(self.rawValue)"
    }

    var code: Int {
        switch self { // μ—¬κΈ°μ„œ selfλŠ” μžμ‹ μ˜ μΌ€μ΄μŠ€λ₯Ό 의미
        case .OK: return 2022
        case .NOT_MODIFY: return 2023
        //...
        }
    }

    func getDescription () -> String { // λ©”μ†Œλ“œ 포함 κ°€λŠ₯ (μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œ)
        switch self { // μ—¬κΈ°μ„œ selfλŠ” μžμ‹ μ˜ μΌ€μ΄μŠ€λ₯Ό 의미
        case .OK:
            return "HTTP μ½”λ“œλŠ” \(self.rawValue) μž…λ‹ˆλ‹€"
        //...
        }
    }
        
    static func getName() -> String { // νƒ€μž… λ©”μ†Œλ“œ
        return "이건 HTTPCodeμ•Ό~~"
    }
}


Self πŸ†š self

πŸ‘‰ Self : νƒ€μž… ν”„λ‘œνΌν‹°μ™€ νƒ€μž… λ©”μ†Œλ“œλ₯Ό 가리킬 λ•Œ μ‚¬μš©
πŸ‘‰ self : μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°μ™€ μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œλ₯Ό 가리킬 λ•Œ μ‚¬μš©


ν”„λ‘œνΌν‹° μ’…λ₯˜ 3가지

πŸ‘‰ μ €μž₯ ν”„λ‘œνΌν‹° : 클래슀/ꡬ쑰체 μ—μ„œ μ‚¬μš©
γ€€γ€€πŸ‘‰ 클래슀/ꡬ쑰체의 μΈμŠ€ν„΄μŠ€μ˜ 일뢀가 λ˜λŠ” μƒμˆ˜(let) 및 λ³€μˆ˜(var)
γ€€γ€€πŸ‘‰ let으둜 μ„ μ–Έλœ μ €μž₯ ν”„λ‘œνΌν‹°λŠ” μˆ˜μ • λΆˆκ°€λŠ₯
γ€€γ€€πŸ‘‰ var둜 μ„ μ–Έλœ μ €μž₯ ν”„λ‘œνΌν‹°λŠ” μˆ˜μ • κ°€λŠ₯
γ€€γ€€πŸ‘‰ μ„ μ–Έ μ‹œ μ΄ˆκΈ°κ°’μ„ 지정할 수 있으며, μˆ˜μ • λ˜ν•œ κ°€λŠ₯
γ€€γ€€πŸ‘‰ lazy μ €μž₯ ν”„λ‘œνΌν‹°
γ€€γ€€γ€€γ€€πŸ‘‰ ν•΄λ‹Ή μ €μž₯ ν”„λ‘œνΌν‹°λŠ” μ‚¬μš©λ˜κΈ° μ „κΉŒμ§€ μƒμ„±λ˜μ§€ μ•ŠμŒ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ”°λΌμ„œ, 잘 ν™œμš©ν•  경우 μ„±λŠ₯ ν–₯상, 곡간낭비λ₯Ό 쀄일 수 μžˆλ‹€λŠ” μž₯점이 있음
γ€€γ€€γ€€γ€€πŸ‘‰ λ°˜λ“œμ‹œ var둜 μ„ μ–Έλ˜μ–΄μ•Ό 함
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ let으둜 μ„ μ–Έλœ ν”„λ‘œνΌν‹°λŠ” μ΄ˆκΈ°ν™”λ₯Ό 함과 λ™μ‹œμ— 값을 ν•„μš”λ‘œ ν•˜κΈ° λ•Œλ¬Έμ—, 값이 ν•„μš”ν•  λ•Œμ— μ΄ˆκΈ°ν™”λ₯Ό ν•˜λŠ” lazyμ™€λŠ” 거리가 있음
πŸ‘‹ Link


πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹° : 클래슀/ꡬ쑰체/μ—΄κ±°ν˜• μ—μ„œ μ‚¬μš©
γ€€γ€€πŸ‘‰ λ°˜λ“œμ‹œ var둜 μ„ μ–Έν•΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹°λ‹ˆκΉŒ 값이 λ³€κ²½λ˜μ–΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ μ—°μ‚°λœ 값을 μ €μž₯ν•  곡간, 즉, λ‹€λ₯Έ λ³€μˆ˜(μ €μž₯ ν”„λ‘œνΌν‹°)λ₯Ό λ°˜λ“œμ‹œ ν•„μš”λ‘œ 함
γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹°λŠ” get, set λ©”μ„œλ“œ 가지고 있음
γ€€γ€€γ€€γ€€πŸ‘‰ get만 μ„ μ–Έ O (읽기 μ „μš©)
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ get만 μžˆλŠ” 읽기 μ „μš© μ—°μ‚° ν”„λ‘œνΌν‹°λŠ” get μƒλž΅ κ°€λŠ₯
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 즉, λ‹¨μˆœνžˆ { return } 으둜 μž‘μ„± κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ get/set μ„ μ–Έ O (읽기/μ“°κΈ°)
γ€€γ€€γ€€γ€€πŸ‘‰ set만 μ„ μ–Έ X
γ€€γ€€πŸ‘‰ get의 return νƒ€μž…μ€ μ—°μ‚° ν”„λ‘œνΌν‹°μ˜ νƒ€μž…κ³Ό λ°˜λ“œμ‹œ κ°™μ•„μ•Ό 함
γ€€γ€€πŸ‘‰ set은 μž‘μ„± 방식, 두 가지
γ€€γ€€γ€€γ€€πŸ‘‰ set { x(μ €μž₯ ν”„λ‘œνΌν‹°) = newValue + 1 }
γ€€γ€€γ€€γ€€πŸ‘‰ set(tempX) { x(μ €μž₯ ν”„λ‘œνΌν‹°) = tempX + 1 }
γ€€γ€€πŸ‘‰ ex)

struct Info {
    var num = 3 // μ €μž₯ ν”„λ‘œνΌν‹°

    var cal: Int { // μ—°μ‚° ν”„λ‘œνΌν‹°
        get {
            let tempX = num + 3

            return tempX // return νƒ€μž… 유의
        }
        set(value) {
            num = value - 3
        }
    }
}

πŸ‘‹ Link


πŸ‘‰ νƒ€μž… ν”„λ‘œνΌν‹° : 클래슀/ꡬ쑰체/μ—΄κ±°ν˜• μ—μ„œ μ‚¬μš©
γ€€γ€€πŸ‘‰ static ν‚€μ›Œλ“œλ₯Ό λΆ™μž„μœΌλ‘œμ¨ νƒ€μž… ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•  수 있음
γ€€γ€€πŸ‘‰ νƒ€μž… ν”„λ‘œνΌν‹°μ—λŠ” μ €μž₯ νƒ€μž… ν”„λ‘œνΌν‹°, μ—°μ‚° νƒ€μž… ν”„λ‘œνΌν‹°κ°€ 있음
γ€€γ€€πŸ‘‰ μ €μž₯ νƒ€μž… ν”„λ‘œνΌν‹°
γ€€γ€€γ€€γ€€πŸ‘‰ let / var둜 μ„ μ–Έ κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ 무쑰건 기본값을 μ„€μ •ν•΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ 처음 μ•‘μ„ΈμŠ€ ν•  λ•ŒλŠ” lazy와 같이 μžλ™μœΌλ‘œ 지연 μ΄ˆκΈ°ν™”
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 즉, lazy ν‚€μ›Œλ“œλŠ” ν•„μš” X
γ€€γ€€πŸ‘‰ μ—°μ‚° νƒ€μž… ν”„λ‘œνΌν‹°
γ€€γ€€γ€€γ€€πŸ‘‰ λ°˜λ“œμ‹œ var둜 μ„ μ–Έν•΄μ•Ό 함(μ—°μ‚° μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°μ²˜λŸΌ)
γ€€γ€€γ€€γ€€πŸ‘‰ 클래슀 νƒ€μž…μ— λŒ€ν•œ μ—°μ‚° νƒ€μž… ν”„λ‘œνΌν‹°μ˜ 경우 static λŒ€μ‹  class ν‚€μ›Œλ“œλ₯Ό λΆ™μž„μœΌλ‘œμ¨ μ„œλΈŒ ν΄λž˜μŠ€κ°€ 슈퍼 클래슀의 κ΅¬ν˜„μ„ μ˜€λ²„λΌμ΄λ“œ ν•  수 있음
γ€€γ€€γ€€γ€€πŸ‘‰ μ„œλΈŒ ν΄λž˜μŠ€μ—μ„œ static ν‚€μ›Œλ“œ μ•žμ— override ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬μ•Ό 함
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ override static var ~
γ€€γ€€γ€€γ€€πŸ‘‰ νƒ€μž… ν”„λ‘œνΌν‹°λŠ” νƒ€μž… μžμ²΄μ— .μ—°μ‚°μžλ₯Ό 톡해 ν”„λ‘œνΌν‹°μ— μ ‘κ·Ό
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ°˜λ©΄μ—, μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λŠ” μΈμŠ€ν„΄μŠ€μ— .μ—°μ‚°μžλ₯Ό 톡해 ν”„λ‘œνΌν‹°μ— μ ‘κ·Ό
πŸ‘‹ Link


Property Observer

πŸ‘‰ ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λŠ” lazy ν‚€μ›Œλ“œκ°€ μ—†λŠ” μ €μž₯ ν”„λ‘œνΌν‹°μ— μΆ”κ°€ν•  수 있음
γ€€γ€€πŸ‘‰ λΆ€λͺ¨ 클래슀의 μ—°μ‚° ν”„λ‘œνΌν‹°λ₯Ό μ˜€λ²„λΌμ΄λ”© ν•  경우 λ˜ν•œ ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•˜λŠ” 것이 κ°€λŠ₯
πŸ‘‰ willSet
γ€€γ€€πŸ‘‰ 값이 μ„€μ •λ˜κΈ° 직전에 ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œ, μƒˆλ‘­κ²Œ 섀정될 값이 newValue
γ€€γ€€πŸ‘‰ willSet μž‘μ„± 방식, 두 가지
γ€€γ€€γ€€γ€€πŸ‘‰ willSet { newValue }
γ€€γ€€γ€€γ€€πŸ‘‰ willSet(A) { A }
πŸ‘‰ didSet
γ€€γ€€πŸ‘‰ μƒˆλ‘œμš΄ 값이 μ„€μ •λœ 직후에 ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œ, μƒˆλ‘œ μ„€μ •λ˜κΈ° μ΄μ „μ˜ 값이 oldValue
γ€€γ€€πŸ‘‰ didSet μž‘μ„± 방식, 두 가지
γ€€γ€€γ€€γ€€πŸ‘‰ didSet { oldValue }
γ€€γ€€γ€€γ€€πŸ‘‰ oldSet(B) { B }
πŸ‘‰ ex)

class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("totalSteps을 \(newTotalSteps)둜 μ„€μ •ν•˜λ €κ³  ν•©λ‹ˆλ‹€.")
        }
        
        didSet(oldTotalSteps) {
            if totalSteps > oldTotalSteps  {
                print("\(totalSteps - oldTotalSteps)걸음이 μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
            }
        }
    }
}

let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// totalSteps을 200둜 μ„€μ •ν•˜λ €κ³  ν•©λ‹ˆλ‹€. (willSet)
// 200(200 - 0)걸음이 μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€. (didSet)


Struct πŸ†š Class πŸ†š Enum

πŸ‘‰ struct와 enum의 μΈμŠ€ν„΄μŠ€λŠ” κ°’ νƒ€μž…μ΄μ§€λ§Œ, class의 μΈμŠ€ν„΄μŠ€λŠ” μ°Έμ‘° νƒ€μž…
πŸ‘‰ struct와 enum은 상속이 λΆˆκ°€λŠ₯ν•˜μ§€λ§Œ, classλŠ” 상속이 κ°€λŠ₯
πŸ‘‰ struct와 classλŠ” μƒμ„±μžκ°€ μžˆμ§€λ§Œ, enumμ—λŠ” μƒμ„±μžκ°€ μ—†μŒ
⭐️ ν΄λž˜μŠ€μ™€ ꡬ쑰체의 곡톡점, 차이점
γ€€γ€€πŸ‘‰ ꡬ쑰체 : κ°’ νƒ€μž…
γ€€γ€€γ€€γ€€πŸ‘‰ var μ„ μ–Έ μ‹œ var μ €μž₯ ν”„λ‘œνΌν‹° κ°’ λ³€κ²½ κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ let μ„ μ–Έ μ‹œ λͺ¨λ“  μ €μž₯ ν”„λ‘œνΌν‹° μƒμˆ˜ν™” λ˜μ–΄ κ°’ λ³€κ²½ λΆˆκ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ μƒμ„±μžκ°€ 없어도 됨
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 기본적으둜 μ €μž₯ ν”„λ‘œνΌν‹°λ“€μ„ νŒŒλΌλ―Έν„°λ‘œ κ°€μ§€λŠ” μ΄λ‹ˆμ…œλΌμ΄μ Έκ°€ 있으며 μ΄ˆκΈ°κ°’μ„ μ€€λ‹€λ©΄ 후에 값을 섀정해주지 μ•Šμ•„λ„ 됨
γ€€γ€€πŸ‘‰ 클래슀 : μ°Έμ‘° νƒ€μž…
γ€€γ€€γ€€γ€€πŸ‘‰ let/var μ„ μ–Έ 관계 없이 var μ €μž₯ ν”„λ‘œνΌν‹° κ°’ λ³€κ²½ κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ let μ €μž₯ ν”„λ‘œνΌν‹°λŠ” λ³€κ²½ λΆˆκ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ μ €μž₯ ν”„λ‘œνΌν‹°μ— μ΄ˆκΈ°κ°’μ΄ μ—†μœΌλ©΄ μƒμ„±μž(init) λ°˜λ“œμ‹œ ν•„μš”
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 단, μ €μž₯ ν”„λ‘œνΌν‹°μ— μ΄ˆκΈ°κ°’μ΄ μ§€μ •λ˜μ–΄ μžˆλ‹€λ©΄ μƒμ„±μžκ°€ 없어도 됨


class μ„±λŠ₯ ν–₯상 방법 πŸ”₯

πŸ‘‰ 상속이 μ—†λŠ” ν΄λž˜μŠ€λŠ” final둜 μ„ μ–Έν•˜κΈ°
γ€€γ€€πŸ‘‰ class μ„±λŠ₯ ν–₯상은 Dispatch κ³Όμ • κ΄€λ ¨
γ€€γ€€πŸ‘‰ Dispatch? μ–΄λ– ν•œ λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•˜μ—¬ μ²˜λ¦¬ν•  지 κ²°μ •ν•˜λŠ” κ³Όμ • (바인딩 in C++)
γ€€γ€€πŸ‘‰ Dispatch μ’…λ₯˜?
γ€€γ€€γ€€γ€€πŸ‘‰ Static Dispatch : 컴파일 μ‹œμ μ— μ–΄λ–€ λ©”μ†Œλ“œκ°€ μ‚¬μš©λ  지 κ²°μ •
γ€€γ€€γ€€γ€€πŸ‘‰ Dynamic Dispatch : λŸ°νƒ€μž„ μ‹œμ μ—μ„œ μ–΄λ–€ λ©”μ†Œλ“œκ°€ μ‚¬μš©λ  지 κ²°μ •
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ Dynamic DispatchλŠ” 참쑰에 따라 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έμ— overheadκ°€ λ°œμƒ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ μ΄λŸ¬ν•œ overheadλŠ” 상속이 κ°€λŠ₯ν•œ class의 override 될 수 μžˆλŠ” λ©”μ†Œλ“œμ—μ„œ λ°œμƒ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ”°λΌμ„œ, overrideκ°€ ν™•μ‹€νžˆ λ˜μ§€ μ•ŠμŒμ„ μ»΄νŒŒμΌλŸ¬μ—κ²Œ μ•Œλ €μ£Όλ©΄ overheadκ°€ λ°œμƒν•˜μ§€ μ•Šμ•„ μ„±λŠ₯이 ν–₯상
πŸ‘‰ μ™ΈλΆ€ 접근이 μ—†λŠ” 경우 private ν‚€μ›Œλ“œ μ‚¬μš©ν•˜κΈ°
πŸ‘‰ 변경이 μ—†λŠ” λ³€μˆ˜λŠ” let ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ°
πŸ‘‰ λ³€μˆ˜ μ„ μ–Έ μ‹œ νƒ€μž…μ„ μ§€μ •ν•˜κΈ°


Optional

πŸ‘‰ nil의 ν—ˆμš© μ—¬λΆ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 것
πŸ‘‰ μ˜΅μ…”λ„ μ’…λ₯˜ 2가지
γ€€γ€€πŸ‘‰ ? : μ˜΅μ…”λ„
γ€€γ€€γ€€γ€€πŸ‘‹ ex)

var optionalValue: Int? = 100  

optionalValue = optionalValue + 1 // κΈ°μ‘΄ λ³€μˆ˜μ²˜λŸΌ μ‚¬μš© λΆˆκ°€
optionalValue = nil // nil ν• λ‹Ή κ°€λŠ₯

γ€€γ€€πŸ‘‰ ! : λ¬΅μ‹œμ  μΆ”μΆœ μ˜΅μ…”λ„
γ€€γ€€γ€€γ€€πŸ‘‰ Non-Optional Type으둜 μ²˜λ¦¬λ˜μ–΄μ•Ό ν•  λ•Œ 값을 μžλ™μœΌλ‘œ μΆ”μΆœν•΄μ£ΌλŠ” μž₯점이 있음
γ€€γ€€γ€€γ€€πŸ‘‰ 잘λͺ» μ‚¬μš© μ‹œ, λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•  수 있음

var optionalValue: Int! = 100

optionalValue = optionalValue + 1 // κΈ°μ‘΄ λ³€μˆ˜μ²˜λŸΌ μ‚¬μš© κ°€λŠ₯
optionalValue = nil // nil ν• λ‹Ή κ°€λŠ₯
optionalValue = optionalValue + 1 // μ˜΅μ…”λ„μ— nil이 ν• λ‹Ήλ˜μ–΄ μžˆμ„ λ•Œ μ ‘κ·Ό μ‹œλ„ -> λŸ°νƒ€μž„ 였λ₯˜


Optional ν•΄μ œ

πŸ‘‰ λͺ…μ‹œμ  ν•΄μ œ
γ€€γ€€πŸ‘‰ κ°•μ œ μ–Έλž˜ν•‘ : ! ν‚€μ›Œλ“œ μ‚¬μš©

var number: Int? = 3

print(number) // Optional(3)
print(number!) // 3

γ€€γ€€πŸ‘‰ λΉ„κ°•μ œ μ–Έλž˜ν•‘ : μ˜΅μ…”λ„ 바인딩

if let result = number { // μ˜΅μ…”λ„ 바인딩
    print(result)
} else {
    print("nil")
}

πŸ‘‰ λ¬΅μ‹œμ  ν•΄μ œ
γ€€γ€€πŸ‘‰ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•œ μžλ™ ν•΄μ œ

let value: Int? = 6

if value == 6 { // 비ꡐ μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜μ—¬ λ‹€λ₯Έ κ°’κ³Ό 비ꡐ ν•  경우, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μ μœΌλ‘œ μ˜΅μ…”λ„ 값을 ν•΄μ œ
    print("valueκ°€ 6μž…λ‹ˆλ‹€.")
} else {
    print("valueκ°€ 6이 μ•„λ‹™λ‹ˆλ‹€.")
}

γ€€γ€€πŸ‘‰ μ˜΅μ…”λ„μ˜ λ¬΅μ‹œμ  ν•΄μ œ

let str = "12"
var strToInt: Int? = Int(str)
// Int() ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜μ— μ •μˆ˜λ‘œ λ³€ν™˜λ  수 μ—†λŠ” 값이 였면
// nil을 λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— μ˜΅μ…”λ„ νƒ€μž…μœΌλ‘œ μ„ μ–Έν•΄μ•Ό ν•œλ‹€.

print(strToInt) // Optional(12)

var strToInt2: Int! = Int(str)
// μ„ μ–Έ μ‹œμ— ! ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ λ¬΅μ‹œμ μœΌλ‘œ μ˜΅μ…”λ„ ν•΄μ œλ₯Ό ν•΄μ€€λ‹€.
// κ°•μ œ μ–Έλž˜ν•‘ λ•Œ μ‚¬μš©ν•˜λŠ” ! μ™€λŠ” μ˜λ―Έκ°€ 닀름

print(strToInt2 + 1) // 13


Optional Binding

πŸ‘‰ 미리 nil 체크λ₯Ό 함과 λ™μ‹œμ— Optional 포μž₯지λ₯Ό 벗겨 값을 μ•ˆμ „ν•˜κ²Œ κΊΌλ‚΄μ˜€λŠ” 방식
πŸ‘‰ 값이 μžˆμ„ λ•Œλ§Œ 값이 바인딩 됨
πŸ‘‰ 주둜 if let, if var, guard 와 ν•¨κ»˜ μ‚¬μš©
γ€€γ€€πŸ‘‰ guard : ν•œ μ€„μ§œλ¦¬ κ°„νŽΈν•œ if ꡬ문, ꡬ문 뒀에 항상 elseλ₯Ό λ‹¬μ•„μ€˜μ•Ό 함
πŸ‘‰ μ‰Όν‘œλ₯Ό μ‚¬μš©ν•΄ μ—¬λŸ¬ μ˜΅μ…”λ„ λ³€μˆ˜λ“€μ„ ν•œκΊΌλ²ˆμ— 바인딩할 수 있음
γ€€γ€€πŸ‘‹ ex)

if let name = myName, let friend = yourName {
    print("μ‹€ν–‰ : \(name) and \(friend)")
} else { // 바인딩 μ‹€νŒ¨ μ‹œ (ν•˜λ‚˜λΌλ„ nil이 μ‘΄μž¬ν•˜λŠ” 경우)
    print("Binding Error")
}


Optional Chaining

πŸ‘‰ ν•˜μœ„ ν”„λ‘œνΌν‹°μ— μ˜΅μ…”λ„ 값이 μžˆλŠ”μ§€ μ—°μ†μ μœΌλ‘œ ν™•μΈν•˜λ©΄μ„œ 쀑간에 ν•˜λ‚˜λΌλ„ nil이 λ°œκ²¬λœλ‹€λ©΄ nil을 λ°˜ν™˜ν•˜λŠ” 것
πŸ‘‹ let count: Int? = A.num?.count


typealias

πŸ‘‰ 기쑴에 μ„ μ–Έλ˜μ–΄ μžˆλŠ” μœ ν˜•μ— μƒˆλ‘œμš΄ μœ ν˜•μ˜ 별칭을 μ‚¬μš©ν•¨μœΌλ‘œμ¨ μ½”λ“œμ˜ μ˜λ―Έμ™€ 가독성을 λ†’μ΄λŠ” κ°œλ…
πŸ‘‹ ex)

typealias Hi = (Int, Int, Int)
typealias Hello = (title: Int, content: Int, writer: Int)

var hi: Hi = (3, 3, 3)
var hi2 = Hi(4, 4, 4)

var hello: Hello = (title: 1, content: 2, writer: 3)
var hello2 = Hello(title: 4, content: 5, writer: 6)

print(hi.0) // 3
print(hi2.0) // 4

print(hello.title) // 1
print(hello2.writer) // 6


νƒ€μž… μΊμŠ€νŒ…

πŸ‘‰ is : νƒ€μž… 확인 및 μ„œλΈŒν΄λž˜μŠ€ 확인
πŸ‘‰ as : νƒ€μž… λ³€ν™˜
γ€€γ€€πŸ‘‰ μ—…μΊμŠ€νŒ… : μ„œλΈŒν΄λž˜μŠ€λ₯Ό 슈퍼클래슀둜 λ§Œλ“œλŠ” 것, 항상 성곡
γ€€γ€€πŸ‘‰ λ‹€μš΄μΊμŠ€νŒ… : 슈퍼클래슀λ₯Ό μ„œλΈŒν΄λž˜μŠ€λ‘œ λ§Œλ“œλŠ” 것, μ‹€νŒ¨ν•  수 μžˆκΈ°μ— as? ν˜Ήμ€ as! μ‚¬μš©


Swift Method

πŸ‘‰ Instance Method
γ€€γ€€πŸ‘‰ μΈμŠ€ν„΄μŠ€ν™”ν•˜μ—¬ μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ₯Ό 톡해 ν˜ΈμΆœν•  수 μžˆλŠ” λ©”μ†Œλ“œ
πŸ‘‰ Type Method
γ€€γ€€πŸ‘‰ μΈμŠ€ν„΄μŠ€μ˜ 생성 없이 νƒ€μž… μžμ²΄μ—μ„œ λ°”λ‘œ ν˜ΈμΆœν•  수 μžˆλŠ” λ©”μ†Œλ“œ
γ€€γ€€πŸ‘‰ Static Method
γ€€γ€€γ€€γ€€πŸ‘‰ subclassμ—μ„œ μ˜€λ²„λΌμ΄λ”©μ΄ λΆˆκ°€λŠ₯ν•œ λ©”μ†Œλ“œ
γ€€γ€€πŸ‘‰ Class Method
γ€€γ€€γ€€γ€€πŸ‘‰ subclassμ—μ„œ μ˜€λ²„λΌμ΄λ”©μ΄ κ°€λŠ₯ν•œ λ©”μ†Œλ“œ


Swift init

πŸ‘‰ Designated init
γ€€γ€€πŸ‘‰ Swift의 μ΄ˆκΈ°ν™” μ΄λ‹ˆμ…œλΌμ΄μ Έλ‘œ, 클래슀의 λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”μ‹œν‚€λŠ” μ—­ν• 
γ€€γ€€πŸ‘‰ init 이라고도 뢈림
γ€€γ€€γ€€γ€€πŸ‘‰ λͺ¨λ“  ν”„λ‘œνΌν‹°λ“€μ€ init ν•¨μˆ˜κ°€ λλ‚˜κΈ° μ „(μ΄ˆκΈ°ν™” μ’…λ£Œ μ „)에 λͺ¨λ‘ μ΄ˆκΈ°κ°’μ„ 가지고 μžˆμ–΄μ•Ό 함
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ§Œμ•½ μ΄ˆκΈ°κ°’μ΄ μ—†λŠ” ν”„λ‘œνΌν‹°κ°€ μžˆμ„ 경우, μ΄ˆκΈ°ν™”μ— μ‹€νŒ¨ν•˜μ—¬ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜μ§€ μ•ŠμŒ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ ν”„λ‘œνΌν‹° νƒ€μž…μ„ μ˜΅μ…”λ„ νƒ€μž…μœΌλ‘œ μ„€μ •ν•˜λŠ” 것 λ˜ν•œ μ΄ˆκΈ°ν™”λ₯Ό μ§„ν–‰ν•œ κ²ƒμž„ (nil둜 μžλ™ μ΄ˆκΈ°ν™”)
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ let으둜 μ„ μ–Έλœ ν”„λ‘œνΌν‹° νƒ€μž…μ„ μ˜΅μ…”λ„ νƒ€μž…μœΌλ‘œ 지정할 경우 λ°˜λ“œμ‹œ μ΄ˆκΈ°κ°’μ„ 지정해야 함, 그렇지 μ•ŠμœΌλ©΄ μ—λŸ¬
γ€€γ€€γ€€γ€€πŸ‘‰ 상속 받은 μ„œλΈŒ ν΄λž˜μŠ€μ—μ„œ D.I.λ₯Ό μž‘μ„±ν•  경우, λ°˜λ“œμ‹œ super 클래슀의 Initializersλ₯Ό ν˜ΈμΆœν•΄μ£Όμ–΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ ex)

class Human {
    let name: String
    var age: Int? // OK
    let num: Int? // Error!
    
    init(name: String) {
        self.name = name
    }
}
 
class Sodeul: Human {
    let alias: String
    
    init(alias: String) { 
        super.init(name: alias) // μ—†μœΌλ©΄ μ—λŸ¬ λ°œμƒ
        self.alias = alias
    }
}

πŸ‘‰ Convinience init
γ€€γ€€πŸ‘‰ 보쑰 μ΄λ‹ˆμ…œλΌμ΄μ Έλ‘œ, 일뢀 ν”„λ‘œνΌν‹°λ₯Ό μ›ν•˜λŠ” κ°’μœΌλ‘œ μ €μž₯ν•˜λŠ” 역할을 ν•˜κΈ°μ— C.i. λ‚΄λΆ€μ—μ„œ λ°˜λ“œμ‹œ D.i.λ₯Ό ν˜ΈμΆœν•΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”ν•΄μ£ΌλŠ” D.i.λ₯Ό λ„μ™€μ£ΌλŠ” μ—­ν• 
γ€€γ€€γ€€γ€€πŸ‘‰ ex)

class Human {
    var name: String
    var nickName: String
    
    init(name: String, nickName: String) {
        self.name = name
        self.nickName = nickName
    }
    
    convenience init(name: String) {
        self.init(name: name, nickName: "unknown")
    }
}

πŸ‘‹ Link


Swift μ΄ˆκΈ°ν™” 심화 κ°œλ… πŸ”₯

πŸ‘‰ Initializer Delegation
γ€€γ€€πŸ‘‰ μƒμ„±μžμ—μ„œ 또 λ‹€λ₯Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ΄ˆκΈ°ν™” μ½”λ“œμ˜ 쀑볡을 μ΅œλŒ€ν•œ μ œκ±°ν•˜κ³ , λͺ¨λ“  ν”„λ‘œνΌν‹°λ₯Ό 효율적으둜 μ΄ˆκΈ°ν™” ν•˜κΈ°μœ„ν•΄ μ‚¬μš©ν•˜λŠ” 것
γ€€γ€€πŸ‘‰ Wrong ex)

struct Position { // Initializer Delegation μ€€μˆ˜ X
    var x: Int
    var y: Int
    
    // λ§Œμ•½, Initializerμ—μ„œ yλ₯Ό 무쑰건 0으둜 μ΄ˆκΈ°ν™” ν•˜κ³  μ‹Άλ‹€λ©΄

    init(xPos: Int, yPos: Int) {
        x = xPos
        y = yPos // 이 곳을 y = 0으둜 μˆ˜μ •ν•΄μ•Όν•˜κ³ 
    }

    init(pos: Int) {
        x = pos
        y = pos // 이 κ³³ λ˜ν•œ, y = 0으둜 μˆ˜μ •ν•΄μ•Ό 함 -> μ½”λ“œ 쀑볡
    }
}

γ€€γ€€πŸ‘‰ Correct ex)

struct Position { // Initializer Delegation μ€€μˆ˜ O
    var x: Int
    var y: Int

    // λ§Œμ•½, Initializerμ—μ„œ yλ₯Ό 무쑰건 0으둜 μ΄ˆκΈ°ν™” ν•˜κ³  μ‹Άλ‹€λ©΄
    
    init(xPos: Int, yPos: Int) {
        x = xPos
        y = yPos // 이 곳만 y = 0으둜 μˆ˜μ •ν•˜λ©΄ 끝 :)
    }

    init(pos: Int) {
        self.init(xPos: pos, yPos: pos)
    }
}

πŸ‘‹ Link


πŸ‘‰ deinit
γ€€γ€€πŸ‘‰ μ†Œλ©Έμžλ‘œ, 클래슀 μΈμŠ€ν„΄μŠ€κ°€ λ©”λͺ¨λ¦¬μ—μ„œ ν•΄μ œλ˜κΈ° 직전에 호좜됨
πŸ‘‰ required init?
γ€€γ€€πŸ‘‰ code ex)

class SampleView: UIView {
    override init(frame: CGRect) {
        //code
    }

    required init?(coder: NSCoder) {
        //code
    }
}

γ€€γ€€πŸ‘‰ μ‰½κ²Œ 말해, UIView/UIViewControllerλ₯Ό μƒμ†λ°›λŠ” ν΄λž˜μŠ€μ—μ„œ ν”„λ‘œνΌν‹°λ₯Ό μ„ μ–Έν•˜κ³  init() λ©”μ†Œλ“œλ₯Ό μž‘μ„±ν•  것인데, μŠˆνΌν΄λž˜μŠ€κ°€ NSCoding ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜κΈ°μ—, required init?(coder: NSCoder) λ©”μ†Œλ“œλ₯Ό μž‘μ„±ν•΄μ•Ό 함
γ€€γ€€γ€€γ€€πŸ‘‰ NSCoding ν”„λ‘œν† μ½œμ€ 이λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€λ‘œλΆ€ν„° μ‹€νŒ¨ κ°€λŠ₯ν•œ μ΄λ‹ˆμ…œλΌμ΄μ €λ₯Ό μž‘μ„±ν•˜λ„λ‘ 함
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ ν΄λž˜μŠ€κ°€ encoding κ³Ό decoding λ˜λŠ” 것을 κ°€λŠ₯ν•˜κ²Œ ν•΄μ£ΌλŠ” ν”„λ‘œν† μ½œ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ‹€μ‹œ λ§ν•˜λ©΄, NSCoding을 μ±„νƒν•œ ν΄λž˜μŠ€λŠ” encoding 및 decoding κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ ν”„λ‘œν† μ½œμ— μ ν˜€μžˆλŠ” μ΄λ‹ˆμ…œλΌμ΄μ €λ₯Ό κ΅¬ν˜„ν•˜λ©΄ required ν‚€μ›Œλ“œκ°€ λΆ™μœΌλ©°, required ν‚€μ›Œλ“œκ°€ 뢙은 μ΄λ‹ˆμ…œλΌμ΄μ €λ₯Ό μƒμ†λ°›λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œλ„ 이λ₯Ό κ΅¬ν˜„ν•΄μ€˜μ•Ό ν•  μˆ˜λ„ 있음
γ€€γ€€γ€€γ€€πŸ‘‰ UIView/UIViewControllerλŠ” NSCoding ν”„λ‘œν† μ½œμ„ κ΅¬ν˜„ν•˜κ³  있기 λ•Œλ¬Έμ—, 이λ₯Ό 상속받은 ν΄λž˜μŠ€μ—μ„œλŠ” required init?(coder: )λ₯Ό κ΅¬ν˜„ν•΄μ€˜μ•Ό ν•  μˆ˜λ„ 있음
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 즉, μ•„μ˜ˆ μž‘μ„±μ„ μ•ˆν•˜κ±°λ‚˜, init을 μž‘μ„±ν•œλ‹€λ©΄ λ°˜λ“œμ‹œ 같이 μž‘μ„±ν•΄μ•Ό 함
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ swiftμ—μ„œλŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ 지정 μ΄λ‹ˆμ…œλΌμ΄μ €λ₯Ό λ”°λ‘œ μž‘μ„±ν•˜μ§€ μ•Šμ€ 경우, λΆ€λͺ¨μ˜ μ΄λ‹ˆμ…œλΌμ΄μ Έλ“€μ„ μžλ™μœΌλ‘œ 상속
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ λ”°λΌμ„œ, μƒˆλ‘œμš΄ D.i.λ₯Ό μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž‘μ„±ν•˜μ§€ μ•Šμ•˜μ„ κ²½μš°μ— μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šμ•˜μŒ
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ ν•˜μ§€λ§Œ, μžμ‹ν΄λž˜μŠ€μ—μ„œ μƒˆλ‘œμš΄ D.i.λ₯Ό μž‘μ„±ν•˜κ²Œ λœλ‹€λ©΄, λΆ€λͺ¨ 클래슀의 μ΄λ‹ˆμ…œλΌμ΄μ €λ“€μ΄ μžλ™ μƒμ†ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, required init?(coder: )λ₯Ό κ΅¬ν˜„ν•˜λΌλŠ” μ—λŸ¬κ°€ λ°œμƒ
γ€€γ€€πŸ‘‰ code둜 customν•œ UIView/UIViewController λ“± 무언가λ₯Ό λ§Œλ“€ λ•Œμ— init을 λ°˜λ“œμ‹œ ν•΄μ•Ό ν•˜λŠ” 이유?
γ€€γ€€γ€€γ€€πŸ‘‰ μΈν„°νŽ˜μ΄μŠ€ λΉŒλ”μ—μ„œλŠ” μžλ™μœΌλ‘œ μ΄ˆκΈ°ν™”λ₯Ό ν•΄μ£Όμ§€λ§Œ, μ½”λ“œμ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€ λΉŒλ”λ₯Ό μ‚¬μš©ν•˜λŠ” 게 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μ΄ˆκΈ°ν™”λ₯Ό ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 아무것도 λœ¨μ§€ μ•ŠκΈ° λ•Œλ¬Έ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ μΈν„°νŽ˜μ΄μŠ€ λΉŒλ”μ˜ λŒ€ν‘œμ μΈ μ˜ˆμ‹œ : Storyboard, Xib
γ€€γ€€γ€€γ€€πŸ‘‰ λ‹€μ–‘ν•œ μ‚¬μš© μ˜ˆμ‹œ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‹ override init(frame: CGRect) // UIView
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‹ override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) // UIViewController
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‹ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) // UITableViewCell
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‹ override init(reuseIdentifier: String?) // UITableViewHeaderFooterView
πŸ‘‹ Link
πŸ‘‹ Link


πŸ‘‰ init? πŸ†š init!
γ€€γ€€πŸ‘‰ init? : μ΄ˆκΈ°ν™”μ— μ„±κ³΅ν•˜λ©΄ μ΄ˆκΈ°ν™”λœ μΈμŠ€ν„΄μŠ€κ°€ β€œOptional Typeβ€μœΌλ‘œ 리턴, μ΄ˆκΈ°ν™”μ— μ‹€νŒ¨ν•˜λ©΄ β€œnil”을 리턴
γ€€γ€€πŸ‘‰ init! : μ΄ˆκΈ°ν™”μ— μ„±κ³΅ν•˜λ©΄ μ΄ˆκΈ°ν™”λœ μΈμŠ€ν„΄μŠ€κ°€ β€œNon Optional Typeβ€μœΌλ‘œ 리턴, μ΄ˆκΈ°ν™”μ— μ‹€νŒ¨ν•˜λ©΄ ν¬λž˜μ‹œκ°€ λ°œμƒ


Protocol

πŸ‘‰ λ°˜λ“œμ‹œ κ°€μ Έμ•Ό ν•  ν”„λ‘œνΌν‹°λ‚˜ λ©”μ†Œλ“œλ₯Ό μ •μ˜λ§Œ ν•˜λŠ” 청사진 μ—­ν• 
πŸ‘‰ ν”„λ‘œν† μ½œμ„ μ μš©ν•  κ°μ²΄λŠ”, ν”„λ‘œν† μ½œμ—μ„œ μ •μ˜ν–ˆλ˜ ν”„λ‘œνΌν‹°μ™€ λ©”μ†Œλ“œλ₯Ό λ°˜λ“œμ‹œ κ΅¬ν˜„ν•΄μ•Ό 함


Protocol Property

πŸ‘‰ ν”„λ‘œν† μ½œμ€ ν”„λ‘œνΌν‹°κ°€ μ €μž₯ ν”„λ‘œνΌν‹°μΈμ§€, μ—°μ‚° ν”„λ‘œνΌν‹°μΈμ§€ λͺ…μ‹œν•˜μ§€ μ•ŠμŒ
πŸ‘‰ λŒ€μ‹  읽기만 κ°€λŠ₯ν•œμ§€, 읽기/μ“°κΈ° λͺ¨λ‘κ°€ κ°€λŠ₯ν•œμ§€ λͺ…μ‹œν•΄μ•Ό 함
πŸ‘‰ λ˜ν•œ, ν”„λ‘œν† μ½œμ˜ ν”„λ‘œνΌν‹°λŠ” λ°˜λ“œμ‹œ var둜 μ„ μ–Έλ˜μ•Ό 함
πŸ‘‰ ex)
πŸ‘‰ ν”„λ‘œν† μ½œμ˜ ν”„λ‘œνΌν‹°κ°€ get만 ν•„μš”λ‘œ ν•˜λŠ” 경우, λͺ¨λ“  μ’…λ₯˜μ˜ ν”„λ‘œνΌν‹°μ—μ„œ μš”κ΅¬μ‚¬ν•­μ„ μΆ©μ‘±μ‹œν‚¬ 수 있음
γ€€γ€€πŸ‘‰ μƒμˆ˜ μ €μž₯ ν”„λ‘œνΌν‹°

protocol FullyNamed {
    var fullName: String { get }
}
struct Person: FullyNamed {
    let fullName: String
}
var john = Person(fullName: "John Appleseed")
john.fullName = "Zedd" // error! 'fullName' is a 'let' constant

γ€€γ€€πŸ‘‰ λ³€μˆ˜ μ €μž₯ ν”„λ‘œνΌν‹°

protocol FullyNamed {
    var fullName: String { get }
}
struct Person: FullyNamed {
    var fullName: String
}
var john = Person(fullName: "John Appleseed")
john.fullName = "Zedd" // ok

γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹° get

protocol FullyNamed {
    var fullName: String { get }
}
struct Person: FullyNamed {
    var name: String // μ‹€μ œ κ°’ μ €μž₯될 μ €μž₯ ν”„λ‘œνΌν‹°
    var fullName: String {
        return name
    }
}
var john = Person(name: "John Appleseed")
john.fullName = "Zedd" // error! 'fullName' is a get-only property
print(john.fullName) // ok

γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹° get/set

protocol FullyNamed {
    var fullName: String { get }
}
struct Person: FullyNamed {
    var name: String // μ‹€μ œ κ°’ μ €μž₯될 μ €μž₯ ν”„λ‘œνΌν‹°
    var fullName: String {
        get {
            return name
        }

        set {
            name = newValue
        }
    }
}
var john = Person(name: "John Appleseed")
john.fullName = "Zedd" // ok
print(john.fullName) // ok

πŸ‘‰ ν”„λ‘œν† μ½œμ˜ ν”„λ‘œνΌν‹°κ°€ getκ³Ό set λͺ¨λ‘ ν•„μš”λ‘œ ν•˜λŠ” 경우, μƒμˆ˜ μ €μž₯ ν”„λ‘œνΌν‹°μ™€ 읽기 μ „μš© μ—°μ‚° ν”„λ‘œνΌν‹°κ°€ 될 수 μ—†μŒ
γ€€γ€€πŸ‘‰ μƒμˆ˜ μ €μž₯ ν”„λ‘œνΌν‹°

protocol FullyNamed {
    var fullName: String { get set }
}
struct Person: FullyNamed {
    let fullName: String // error! error: type 'Person' does not conform to protocol 'FullyNamed'
}
var john = Person(fullName: "John Appleseed")

γ€€γ€€πŸ‘‰ λ³€μˆ˜ μ €μž₯ ν”„λ‘œνΌν‹°

protocol FullyNamed {
    var fullName: String { get set }
}
struct Person: FullyNamed {
    var fullName: String
}
var john = Person(fullName: "John Appleseed")
john.fullName = "Zedd" // ok

γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹° get

protocol FullyNamed {
    var fullName: String { get set }
}
struct Person: FullyNamed {
    var name: String // μ‹€μ œ κ°’ μ €μž₯될 μ €μž₯ ν”„λ‘œνΌν‹°
    var fullName: String {
        return name // error! error: type 'Person' does not conform to protocol 'FullyNamed'
    }
}
var john = Person(name: "John Appleseed")

γ€€γ€€πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹° get/set

protocol FullyNamed {
    var fullName: String { get set }
}
struct Person: FullyNamed {
    var name: String // μ‹€μ œ κ°’ μ €μž₯될 μ €μž₯ ν”„λ‘œνΌν‹°
    var fullName: String {
        get {
            return name
        }

        set {
            name = newValue
        }
    }
}
var john = Person(name: "John Appleseed")
john.fullName = "Zedd" // ok
print(john.fullName) // ok


Any πŸ†š AnyObject

πŸ‘‰ AnyλŠ” ν•¨μˆ˜ νƒ€μž…μ„ ν¬ν•¨ν•œ λͺ¨λ“  νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” ν”„λ‘œν† μ½œ
πŸ‘‰ 반면, AnyObjectλŠ” 클래슀 νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ§Œμ„ λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” ν”„λ‘œν† μ½œ


객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ° πŸ†š ν”„λ‘œν† μ½œ 지ν–₯ ν”„λ‘œκ·Έλž˜λ°

πŸ‘‰ 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°
γ€€γ€€πŸ‘‰ 상속을 톡해 수직적으둜 νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” ꡬ쑰
γ€€γ€€πŸ‘‰ ν•˜λ‚˜μ˜ μ„œλΈŒν΄λž˜μŠ€λŠ” ν•˜λ‚˜μ˜ 슈퍼클래슀만 κ°€μ§ˆ 수 μžˆλ‹€λŠ” μ œν•œμ΄ 있음
γ€€γ€€πŸ‘‰ 슈퍼클래슀λ₯Ό κ·ΈλŒ€λ‘œ 상속 받기에 λΆˆν•„μš”ν•œ λ³€μˆ˜μ™€ λ©”μ†Œλ“œλ₯Ό λͺ¨λ‘ λ¬Όλ € λ°›μ•„μ•Ό ν•˜λŠ” 단점
πŸ‘‰ ν”„λ‘œν† μ½œ 지ν–₯ ν”„λ‘œκ·Έλž˜λ°
γ€€γ€€πŸ‘‰ ν”„λ‘œν† μ½œ ν™•μž₯을 톡해 μˆ˜ν‰μ μœΌλ‘œ νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” ꡬ쑰
γ€€γ€€πŸ‘‰ μƒμ†κ³ΌλŠ” λ‹€λ₯΄κ²Œ λ‹€μˆ˜μ˜ ν”„λ‘œν† μ½œμ„ κ°€μ§€λŠ” 것이 κ°€λŠ₯
γ€€γ€€πŸ‘‰ λΆ€λͺ¨ ν”„λ‘œν† μ½œκ³Ό μžμ‹ ν”„λ‘œν† μ½œ 사이가 μ„œλ‘œ 독립적이기에 λΆˆν•„μš”ν•œ ν”„λ‘œνΌν‹°λ‚˜ λ©”μ†Œλ“œλ₯Ό 갖지 μ•Šκ²Œ ν•  수 있음


map

πŸ‘‰ μ»¬λ ‰μ…˜μ΄ λ³΄μœ ν•œ 각 값듀을 λ§€κ°œλ³€μˆ˜λ‘œ 전달받은 ν•¨μˆ˜μ—μ„œ λ‘œμ§μ„ μ²˜λ¦¬ν•œ ν›„ μƒˆλ‘œμš΄ μ»¬λ ‰μ…˜μœΌλ‘œ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜


filter

πŸ‘‰ μ»¬λ ‰μ…˜μ΄ λ³΄μœ ν•œ κ°’λ“€ 쀑 λ§€κ°œλ³€μˆ˜λ‘œ 전달받은 ν•¨μˆ˜μ˜ κ²°κ³Όκ°€ True인 κ°’λ§Œ μƒˆλ‘œμš΄ μ»¬λ ‰μ…˜μ— λ„£μ–΄ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜


reduce

πŸ‘‰ μ΄ˆκΈ°κ°’μ— μ»¬λ ‰μ…˜μ΄ λ³΄μœ ν•œ 각 값듀을 λ§€κ°œλ³€μˆ˜λ‘œ 전달받은 ν•¨μˆ˜μ—μ„œ λͺ¨λ‘ κ³„μ‚°ν•˜μ—¬ μ—°μ‚° 결과둜 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜


flatMap πŸ†š compactMap

πŸ‘‰ Swift 4.1λΆ€ν„° flatMap은 2차원 배열을 1차원 λ°°μ—΄λ‘œ λ§Œλ“œλŠ” μ—­ν• 
γ€€γ€€πŸ‘‰ 기쑴의 flatMap은 배열을 flattenν•˜κ²Œ λ§Œλ“€μ–΄ μ£Όκ³ , nil을 μ œκ±°ν•˜λ©°, μ˜΅μ…”λ„ 바인딩을 ν•˜λŠ” μ—­ν• 
πŸ‘‰ Swift 4.1λΆ€ν„° 1차원 λ°°μ—΄μ—μ„œ nil을 μ œκ±°ν•˜κ³  μ˜΅μ…”λ„ 바인딩을 ν•˜κ³  싢을 λ•Œ compactMap을 μ‚¬μš©
γ€€γ€€πŸ‘‰ compactMap은 2차원 배열을 1차원 λ°°μ—΄λ‘œ λ§Œλ“€μ§€ μ•ŠμŒ
πŸ‘‰ nil이 ν¬ν•¨λœ 2차원 λ°°μ—΄μ—μ„œ flatmapκ³Ό compactmap을 μˆœμ„œλŒ€λ‘œ 체이닝 μ—°κ²°ν•˜λ©΄ 1차원 λ°°μ—΄λ‘œ nil을 μ œκ±°ν•˜κ³  μ˜΅μ…”λ„ 바인딩을 해쀄 수 있음
πŸ‘‰ 1차원 λ°°μ—΄μ—μ„œλŠ” λ™μΌν•œ κ²°κ³Ό


Swift의 sort() κ΅¬ν˜„ 방식?

πŸ‘‰ Insertion Sort와 Merge Sortκ°€ 합쳐진 ν˜•νƒœμΈ Tim Sort둜 κ΅¬ν˜„λ˜μ–΄ 있음
πŸ‘‰ μ‹œκ°„ λ³΅μž‘λ„ : μ΅œμ„ μ˜ 경우 O(n), μ΅œμ•…μ˜ 경우 O(nlogn)


Result

πŸ‘‰ 성곡과 μ‹€νŒ¨μ— λŒ€ν•œ κ²°κ³Ό 값을 λ°˜ν™˜ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•˜λŠ” νƒ€μž…
πŸ‘‰ Result νƒ€μž…μ€ enum이며, 두 개의 μ œλ„€λ¦­ν•œ κ²°κ³Όλ₯Ό 리턴
γ€€γ€€πŸ‘‰ Failure νƒ€μž…μ€ Errorλ₯Ό 상속받은 νƒ€μž…μ΄μ–΄μ•Ό 함
γ€€γ€€πŸ‘‰ Success νƒ€μž…μ€ void, string, int λ“± κ°’ νƒ€μž…μ„ μ‚¬μš©ν•΄λ„ 됨


Subscripts

πŸ‘‰ μ»¬λ ‰μ…˜, 리슀트, μ‹œν€€μŠ€ λ“± μ§‘ν•©μ˜ νŠΉμ • μš”μ†Œμ— μ‰½κ²Œ μ ‘κ·Όν•  수 μžˆλŠ” 문법
πŸ‘‰ λ°°μ—΄μ—μ„œλŠ” 인덱슀λ₯Ό 톡해, λ”•μ…”λ„ˆλ¦¬μ—μ„œλŠ” ν‚€ 값을 톡해 μ ‘κ·Ό
πŸ‘‰ ex)

var dict = ["Kim": 1, "Lee": 2]
dict["Park"] = 3 // Subscript 문법

var arr = [3, 2, 4, 8]
arr[0] = 1 // Subscript 문법
print(arr[0]) // Subscript 문법


Collection πŸ†š Sequence

πŸ‘‰ Collection
γ€€γ€€πŸ‘‰ Collection ν”„λ‘œν† μ½œμ€ Sequence ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜κ³  있음
γ€€γ€€πŸ‘‰ λŒ€ν‘œμ μœΌλ‘œ, Array, Set, Dictionaryκ°€ Collection ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜κ³  있음
πŸ‘‰ Sequence
γ€€γ€€πŸ‘‰ 각 μš”μ†Œμ— 순차적이고 반볡적인 접근이 κ°€λŠ₯ν•œ νƒ€μž…


Copy On Write

πŸ‘‰ 데이터 볡사 μ‹œ μ‹€μ œλ‘œ 값을 λ³΅μ‚¬ν•˜μ§€ μ•Šκ³  λ‹¨μˆœνžˆ 값을 참쑰만 ν•˜λ‹€κ°€ 데이터 변경이 λ°œμƒλ  μ‹œ 값을 볡사해 λ³€κ²½ν•˜λŠ” 기법
πŸ‘‰ Collection Type을 λ³΅μ‚¬ν•΄μ„œ μ‚¬μš©ν•  λ•Œ 일어남
γ€€γ€€πŸ‘‰ Swiftμ—μ„œλŠ” 기본적으둜 Collection νƒ€μž…μ— COWκ°€ κ΅¬ν˜„λ˜μ–΄ 있기 λ•Œλ¬Έ
πŸ‘‰ λ‹¨μˆœνžˆ 값을 참쑰만 ν•˜λ‹€κ°€ 데이터 변경이 λ°œμƒλ  μ‹œ 값을 λ³΅μ‚¬ν•˜μ—¬ λΆˆν•„μš”ν•œ 볡사λ₯Ό μ€„μ΄λŠ” λ§€μ»€λ‹ˆμ¦˜
πŸ‘‰ 기쑴의 μ˜€λ²„ν—€λ“œλ₯Ό 쀄일 수 있음
πŸ‘‰ μƒμ„±λ˜λŠ” 사본 수λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ Reference Countλ₯Ό 계산해야 ν•œλ‹€λŠ” 단점이 쑴재


String of Swift

πŸ‘‰ swiftμ—μ„œ string은 κ°’ νƒ€μž…μœΌλ‘œ λΆ„λ₯˜λ˜λ©°, character의 collection
πŸ‘‰ characterλŠ” 각각 λ‹€λ₯Έ 크기의 λ©”λͺ¨λ¦¬λ₯Ό 차지할 수 μžˆλŠ” μœ λ‹ˆμ½”λ“œλ₯Ό μ€€μˆ˜ν•˜κΈ° λ•Œλ¬Έμ— Subscript둜 μ ‘κ·Ό X
πŸ‘‰ λ˜ν•œ, character νƒ€μž…μ€ νž™ μ˜μ—­μ— κ°„μ ‘μ μœΌλ‘œ μ €μž₯λ˜κΈ°μ—, λ”°λΌμ„œ, String은 κ°’ νƒ€μž…μ΄μ§€λ§Œ νž™ 할당이 λ°œμƒ


String πŸ†š NSString

πŸ‘‰ String
γ€€γ€€πŸ‘‰ ꡬ쑰체, κ°’ νƒ€μž…
πŸ‘‰ NSString
γ€€γ€€πŸ‘‰ 클래슀, μ°Έμ‘° νƒ€μž…


NSAttributedString πŸ†š NSMutableAttributedString

πŸ‘‰ NSAttributedString
γ€€γ€€πŸ‘‰ ν…μŠ€νŠΈ μžμ²΄μ— μŠ€νƒ€μΌμ„ μ„€μ •ν•  수 μžˆλŠ” ν…μŠ€νŠΈ νƒ€μž…
πŸ‘‰ NSMutableAttributedString
γ€€γ€€πŸ‘‰ NSAttributedString의 νŠΉμ • λ²”μœ„μ— λ‹€μ–‘ν•œ μŠ€νƒ€μΌ(색상, μžκ°„ λ“±)을 μ„€μ •ν•  수 μžˆλŠ” ν…μŠ€νŠΈ νƒ€μž…


KVC πŸ”₯

πŸ‘‰ Key-Value Coding
πŸ‘‰ 객체의 값을 직접 κ°€μ Έμ˜€μ§€ μ•Šκ³ , Key λ˜λŠ” KeyPathλ₯Ό μ΄μš©ν•΄μ„œ κ°„μ ‘μ μœΌλ‘œ 데이터λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜ μˆ˜μ •ν•˜λŠ” 방법
πŸ‘‰ ex)

struct Address {
    var town: String
}

struct Person {
    var address: Address
}
let address = Address(town: "Lalala")
var kid = Person(address: address)

kid[keyPath: \.address.town] // Lalala

kid[keyPath: \.address.town] = "Hello"
kid[keyPath: \.address.town] // Hello
kid.address.town // Hello

πŸ‘‹ Link


KVO πŸ”₯

πŸ‘‰ Key-Value Observing
πŸ‘‰ 객체의 ν”„λ‘œνΌν‹°μ˜ 변경사항을 λ‹€λ₯Έ 객체에 μ•Œλ¦¬κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” μ½”μ½”μ•„ ν”„λ‘œκ·Έλž˜λ° νŒ¨ν„΄
πŸ‘‰ Modelκ³Ό View와 같이 λ…Όλ¦¬μ μœΌλ‘œ λΆ„λ¦¬λœ νŒŒνŠΈκ°„μ˜ 변경사항을 μ „λ‹¬ν•˜λŠ”λ° 유용
πŸ‘‰ NSObjectλ₯Ό μƒμ†ν•œ ν΄λž˜μŠ€μ—μ„œλ§Œ KVOλ₯Ό μ‚¬μš©ν•  수 있음
πŸ‘‹ Link


Codable

πŸ‘‰ μžμ‹ μ„ μ™ΈλΆ€ ν‘œν˜„μœΌλ‘œ 인코딩할 수 μžˆλŠ” μœ ν˜•μΈ Encodableκ³Ό μ™ΈλΆ€ ν‘œν˜„μœΌλ‘œλΆ€ν„° μžμ‹ μ„ λ””μ½”λ”©ν•  수 μžˆλŠ” μœ ν˜•μΈ Decodable둜 κ΅¬μ„±λœ ν”„λ‘œν† μ½œ
πŸ‘‰ 주둜, APIμ—μ„œ JSON Dataλ₯Ό λ‹€λ£° λ•Œ μ‚¬μš©
γ€€γ€€πŸ‘‰ JSON Data 쀑 ν•„μš”ν•œ 데이터λ₯Ό λͺ¨λΈλ‘œ μ •λ¦¬ν•œ Struct, Class ν˜Ήμ€ Enum을 톡해 μ‚¬μš©


CodingKey

πŸ‘‰ 주둜 Codable ν”„λ‘œν† μ½œμ—μ„œ JSON Keyλ₯Ό μ‚¬μš©μžκ°€ μ •μ˜ν•œ ν”„λ‘œνΌν‹°μ— λ§€ν•‘ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” ν”„λ‘œν† μ½œ
πŸ‘‰ ex)

struct Coffee: Codable {
    var name: String

    enum CodingKeys: String, CodingKey {
        case name = "order_Drink_Name"
    }
}


Identifiable

πŸ‘‰ Hashable ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λ©°, id ν”„λ‘œνΌν‹° ν•˜λ‚˜λ§Œ κ°€μ§€λŠ” μ•„μ£Ό λ‹¨μˆœν•œ ν”„λ‘œν† μ½œ
πŸ‘‰ μ±„νƒν•œ νƒ€μž…μ˜ idλ₯Ό ν†΅ν•˜μ—¬ 고유 개체λ₯Ό 비ꡐ 및 κ΅¬λΆ„ν•˜κ²Œ λ˜λŠ” 방식
πŸ‘‰ UUID : λ²”μš© 고유 μ‹λ³„μžλ‘œ, κ³ μœ ν•˜κ²Œ μ‹λ³„ν•˜κΈ° μœ„ν•΄ λ§Œλ“€μ–΄μ§„ κ°œλ…
γ€€γ€€πŸ‘‰ 총 36개 문자(32개 λ¬Έμžμ™€ 4개의 ν•˜μ΄ν”ˆ)으둜 κ΅¬μ„±λ˜μ–΄ 있음


Hashable & Equatable

πŸ‘‰ Hashable
γ€€γ€€πŸ‘‰ μ±„νƒν•œ νƒ€μž…μ΄ μœ μΌν•œ κ°’μœΌλ‘œ ꡬ뢄됨을 보μž₯ν•΄μ£ΌλŠ” ν”„λ‘œν† μ½œ
γ€€γ€€πŸ‘‰ λ‚΄λΆ€μ˜ hash function을 톡해 ν•΄μ‹œ 값을 κ²°μ •
γ€€γ€€πŸ‘‰ Hashable은 Equatable ν”„λ‘œν† μ½œμ„ μƒμ†ν•˜κ³  있음
γ€€γ€€γ€€γ€€πŸ‘‰ Hκ°€ Eλ₯Ό 상속해야 ν•˜λŠ” 이유
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 객체의 동일 μ—¬λΆ€λŠ” λͺ…ν™•ν•œ νŒλ‹¨ 기쀀을 ν•„μš”λ‘œ 함
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ Equatable : κ°’μ˜ 비ꡐ가 κ°€λŠ₯함을 보μž₯ν•΄μ£ΌλŠ” ν”„λ‘œν† μ½œ
γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ ==, != μ—°μ‚°μžλ₯Ό μ •μ˜ν•˜μ—¬ 객체의 동일 μ—¬λΆ€μ˜ 기쀀을 결정함
γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€πŸ‘‰ 즉, Equatable ν”„λ‘œν† μ½œμ„ 상속 λ°›μ•„ Hashable νƒ€μž…μ΄ 객체의 동일 μ—¬λΆ€λ₯Ό νŒλ‹¨ν•  수 μžˆλ„λ‘ 함


CaseIterable

πŸ‘‰ enum μ—΄κ±°ν˜•μ˜ 값듀을 λ°°μ—΄ μ»¬λ ‰μ…˜κ³Ό 같이 μˆœνšŒν•  수 μžˆλ„λ‘ ν•΄μ£ΌλŠ” ν”„λ‘œν† μ½œ
πŸ‘‰ 주둜 allCases νƒ€μž… ν”„λ‘œνΌν‹°μ™€ ν•¨κ»˜ 많이 μ“°μž„


Mutating

πŸ‘‰ κ°’ νƒ€μž…μ˜ ν”„λ‘œνΌν‹°λŠ” 기본적으둜 λ©”μ†Œλ“œ λ‚΄λΆ€μ—μ„œ μˆ˜μ •ν•  수 μ—†μŒ
πŸ‘‰ μˆ˜μ •μ΄ ν•„μš”ν•œ 경우 λ©”μ†Œλ“œ μ•žμ— mutating ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜μ •μ΄ κ°€λŠ₯ν•΄ 짐
γ€€γ€€πŸ‘‰ λ©”μ†Œλ“œ λ‚΄μ—μ„œ κ°’ νƒ€μž…μ˜ ν”„λ‘œνΌν‹°λ₯Ό μˆ˜μ •ν•˜λ©΄, ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€μ˜ 볡사본이 μƒμ„±λ˜μ–΄ λ³€κ²½λ˜λŠ” 것
γ€€γ€€πŸ‘‰ 즉, 볡사본이 변경이 λ³€κ²½λ˜μ—ˆμ„ 뿐 μ›λž˜μ˜ μΈμŠ€ν„΄μŠ€μ™€ 무관함
γ€€γ€€πŸ‘‰ mutating은 이 볡사본을 μ›λž˜μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ¦¬ν„΄ν•˜λŠ” μ—­ν• λ‘œ μ΄ν•΄ν•˜λ©΄ 됨


Extension

πŸ‘‰ 이미 μ‘΄μž¬ν•˜λŠ” 클래슀, ꡬ쑰체, ν”„λ‘œν† μ½œ λ“±μ˜ νƒ€μž…μ— μƒˆλ‘œμš΄ κΈ°λŠ₯을 μΆ”κ°€ν•˜μ—¬ ν™•μž₯ν•˜λŠ” κ°œλ…
πŸ‘‰ μ—°μ‚° ν”„λ‘œνΌν‹°, λ©”μ†Œλ“œ, ν”„λ‘œν† μ½œ 등을 μΆ”κ°€ν•  수 있음
πŸ‘‰ 원본 μ†ŒμŠ€ μ½”λ“œμ— μ ‘κ·Όν•  수 μ—†λŠ” μœ ν˜•μ„ ν™•μž₯ν•˜λŠ” κΈ°λŠ₯도 ν¬ν•¨λ˜μ–΄ 있음
πŸ‘‰ extension λ‚΄λΆ€μ—μ„œ ν•¨μˆ˜ μ˜€λ²„λΌμ΄λ”© κ°€λŠ₯ν•œμ§€?
γ€€γ€€πŸ‘‰ ν•΄λ‹Ήν•˜λŠ” λ©”μ†Œλ“œκ°€ Objective-C와 ν˜Έν™˜λ˜λŠ” 경우 μ˜€λ²„λΌμ΄λ”©μ΄ κ°€λŠ₯은 ν•˜μ§€λ§Œ, 일반적으둜 ꢌμž₯λ˜λŠ” 방법은 μ•„λ‹˜
γ€€γ€€πŸ‘‰ κ·Έ μ΄μœ λŠ”, extension은 좔가적인 κΈ°λŠ₯의 ν™•μž₯을 μ‚¬μš©ν•˜λŠ” κ°œλ…μ΄κΈ° λ•Œλ¬Έ


Defer

πŸ‘‰ ν•¨μˆ˜ μ•ˆμ—μ„œ μž‘μ„±λ˜λŠ” ν΄λ‘œμ €
πŸ‘‰ μž‘μ„±λœ μœ„μΉ˜μ™€ 상관없이 ν•¨μˆ˜ μ’…λ£Œ 직전에 싀행됨
πŸ‘‰ ν˜ΈμΆœλ˜λŠ” μˆœμ„œ
γ€€γ€€πŸ‘‰ ν•˜λ‚˜μ˜ μŠ€μ½”ν”„μ—μ„œ μ—¬λŸ¬ deferλ₯Ό μ‚¬μš©ν•  경우 μŠ€νƒμ²˜λŸΌ μŒ“μž„
γ€€γ€€πŸ‘‰ κ°€μž₯ λ¨Όμ € 넣은 defer μ½”λ“œκ°€ κ°€μž₯ λ§ˆμ§€λ§‰μ— 호좜됨
γ€€γ€€πŸ‘‰ κ°€μž₯ λ§ˆμ§€λ§‰μ— 넣은 defer μ½”λ“œκ°€ κ°€μž₯ λ¨Όμ € 호좜됨
πŸ‘‰ deferκ°€ 호좜되기 전에 ν•΄λ‹Ή μŠ€μ½”ν”„κ°€ μ—λŸ¬ λ“±μœΌλ‘œ 인해 μ’…λ£Œλ˜κ±°λ‚˜, 리턴 값이 Never(λΉ„λ°˜ν™˜)인 κ²½μš°μ—λŠ” deferκ°€ ν˜ΈμΆœλ˜μ§€ X


Closure

πŸ‘‰ Named Closure
γ€€γ€€πŸ‘‰ 일반적으둜 이름이 μžˆλŠ” ν•¨μˆ˜
γ€€γ€€πŸ‘‰ ex)

func hello() {
    print("hello")
}

πŸ‘‰ Unnamed Closure
γ€€γ€€πŸ‘‰ 이름 없이 μ‚¬μš©ν•˜λŠ” 읡λͺ…ν•¨μˆ˜
γ€€γ€€πŸ‘‰ 일급 객체 νŠΉμ§•μ„ κ°–κ³  있음
γ€€γ€€γ€€γ€€πŸ‘‰ λ³€μˆ˜μ— 담을 수 있음
γ€€γ€€γ€€γ€€πŸ‘‰ 인자둜 전달 κ°€λŠ₯
γ€€γ€€γ€€γ€€πŸ‘‰ λ°˜ν™˜ 값에 μ‚¬μš© κ°€λŠ₯
γ€€γ€€πŸ‘‰ ν΄λ‘œμ €λŠ” Named C- & Unnamed C- λͺ¨λ‘ ν¬ν•¨ν•˜μ§€λ§Œ, 보톡 Unnamed C-λ₯Ό ν΄λ‘œμ €λΌ 함
γ€€γ€€πŸ‘‰ ex)

let closure = { (name: String) -> String in
    return "Hello, \(name)"
}


Escaping Closure

πŸ‘‰ @escaping ν‚€μ›Œλ“œκ°€ 뢙은 ν΄λ‘œμ €
πŸ‘‰ ν•¨μˆ˜μ˜ 인자둜 ν΄λ‘œμ €λ₯Ό μ „λ‹¬ν•˜λŠ” 방식
γ€€γ€€πŸ‘‰ ν•¨μˆ˜μ˜ 인자둜 μ „λ‹¬λœ ν΄λ‘œμ €λŠ” 기본적으둜 ν•¨μˆ˜μ˜ μŠ€μ½”ν”„ λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜μ—¬, μ™ΈλΆ€ λ³€μˆ˜μ— 담을 수 μ—†μŒ
γ€€γ€€πŸ‘‰ 즉, 기본적으둜 νƒˆμΆœ λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 속성을 가지고 있음
γ€€γ€€πŸ‘‰ λ˜ν•œ, ν•¨μˆ˜μ˜ 인자둜 μ „λ‹¬λœ ν΄λ‘œμ €λŠ” ν•΄λ‹Ή ν•¨μˆ˜κ°€ λλ‚˜κΈ° 이전에 λ°˜λ“œμ‹œ ν•΄λ‹Ή ν΄λ‘œμ €κ°€ 싀행됨
γ€€γ€€πŸ‘‰ 즉, ν•΄λ‹Ή ν•¨μˆ˜κ°€ λλ‚˜κ²Œ 되면 인자둜 λ„˜μ–΄κ°„ ν΄λ‘œμ €λŠ” μ‚¬μš©μ΄ λΆˆκ°€λŠ₯
πŸ‘‰ @escaping ν‚€μ›Œλ“œλ₯Ό λΆ™μž„μœΌλ‘œμ¨, ν•¨μˆ˜κ°€ λ¦¬ν„΄λœ ν›„ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„ λ°–μ—μ„œ ν΄λ‘œμ €λ₯Ό μ‹€ν–‰ν•  수 있음
πŸ‘‰ ν•¨μˆ˜κ°€ λ¦¬ν„΄λœ ν›„ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„ λ°–μ—μ„œ ν΄λ‘œμ €λ₯Ό μ‹€ν–‰ν•  수 μžˆμ–΄ 비동기 μž‘μ—…μ„ μ²˜λ¦¬ν•  λ•Œ μ‚¬μš©ν•¨


Swift Access Control(μ ‘κ·Ό μ œμ–΄μž)

πŸ‘‰ open
γ€€γ€€πŸ‘‰ λͺ¨λ“ˆ μ™ΈλΆ€μ—μ„œ access κ°€λŠ₯
γ€€γ€€πŸ‘‰ λͺ¨λ“ˆ μ™ΈλΆ€ 상속과 override κ°€λŠ₯
πŸ‘‰ public
γ€€γ€€πŸ‘‰ λͺ¨λ“ˆ μ™ΈλΆ€μ—μ„œ access κ°€λŠ₯
γ€€γ€€πŸ‘‰ λͺ¨λ“ˆ μ™ΈλΆ€ 상속과 override λΆˆκ°€λŠ₯
πŸ‘‰ internal(default κ°’)
γ€€γ€€πŸ‘‰ 같은 λͺ¨λ“ˆ μ•ˆμ—μ„œ access κ°€λŠ₯
πŸ‘‰ fileprivate
γ€€γ€€πŸ‘‰ 같은 파일 μ•ˆμ—μ„œ access κ°€λŠ₯
πŸ‘‰ private
γ€€γ€€πŸ‘‰ 같은 μŠ€μ½”ν”„ μ•ˆμ—μ„œ access κ°€λŠ₯



*****
NOT A TALENT ❎ NOT GIVING UP βœ…
CopyRight β“’ 2022 DCherish All Rights Reserved.