Day 13 ~ Day 15 : 복습

sun·2021년 9월 19일
0

100 Days of SwiftUI

목록 보기
8/11

[Day 13]   [Day 14]   [Day 15]

@ Day 13

# 배열

  • Any 타입을 사용하면 여러 타입을 담을 수 있는 배열을 만들 수 있음
	var all: [Any] = ["string", 1, -138923.1293, true]

@ Day 14

# Enumerations

  • 타입 추론이 가능한 경우 enum 의 이름을 생략하고 .caseName 의 형태로 각 케이스를 호출할 수 있음
enum WeatherType {
    case sun, cloud, wind, rain
}

func getHaterStatus(weather: WeatherType) -> String? {
    switch weather {
        case .sun:  // 타입 추론이 가능하므로 생략해서 표기
            return nil
        case .cloud, .wind:
            return "dislike"
        case .rain:
            return "hate"
    }
}

Enums with associated values

  • let-where 구문 을 이용해서 조건문을 추가로 만들 수 있음
enum WeatherType {
    case sun
    case cloud
    case rain
    case wind(speed: Int)
    case snow
}

func getHaterStatus(weather: WeatherType) -> String? {
    switch weather {
        case .sun:
            return nil
        case .wind(let speed) where speed < 10:
            return "meh"
        case .cloud, .wind:
            return "dislike"
        case .rain, .snow:
            return "hate"
    }
}

print(getHaterStatus(weather: .wind(speed: 5))!)  // meh
print(getHaterStatus(weather: .wind(speed: 20))!)  // dislike

# Objective-C

  • 애플 운영체제가 스위프트 클래스의 메서드를 호출하도록 하고 싶다면 해당 메서드에 @objc 로 표기해줘야 함
  • 만약 운영체제가 특정 클래스의 모든 메서드를 호출할 수 있도록 하려면 해당 클래스 앞에 @objcMembers 라고 표기해주면 됨

# class

  • 부모 클래스에서 선언된 상수/변수를 자식 클래스에서 초기화하는 경우 super.init() 사용

@ Day 15

# 프로퍼티 옵저버

  • willSet 은 프로퍼티가 바뀌기 전에 호출되며 newValue 값에 바뀔 값 저장
  • didSet 은 프로퍼티가 바뀌고 난 뒤에 호출되며 oldValue 값에 이전 값 저장
struct Person {
    car clothes: String {
        willSet {
            updateUI(msg: "I'm changing from \(clothes) to \(newValue)")
        }
        
        didSet {
            updateUI(msg: "I just changed from \(oldValue) to \(newValue)")
        }
    }
}

func updateUI(msg: String) {
    print(msg)
}

var sun = Person(clothes: "t-shirts")
sun.clohtes = "jeans"

# 연산 프로퍼티

  • 프로퍼티 이름 뒤의 { } 안에 get 혹은 set 을 이용해서 연산 프로퍼티를 만들 수 있음
struct Person {
    var age: Int
        
    var ageInDogYears: Int {
        get {
            return age * 7
        }
    }
}

var fan = Person(age: 25)
print(fan.ageInDogYears)  // 175
  • 읽기 전용 데이터인 경우 get 을 생략하고 다음과 같이 쓸 수 있음
var ageInDogYears: Int {
    	return age * 7
}

# Static 프로퍼티와 메서드

  • 프로퍼티와 메서드 앞에 static 키워드를 붙이면 인스턴스가 아닌 타입 자체 의 프로퍼티/메서드가 됨

# Access modifiers

  읽기/쓰기 권한의 정도:

  • public : 모두 접근 가능
  • internal : 해당 스위프트 코드 전체에서 접근 가능
  • file private : 동일한 파일에 있는 스위프트 코드에서만 접근 가능
  • private : 해당 타입 혹은 익스텐션에 포함되는 메서드에서만 접근 가능

# 다형성

  • 자녀 클래스는 자녀 클래스인 동시에 부모 클래스인 것처럼 다룰 수 있음
    class Album {
        var name: String
        
        init(name: String) {
            self.name = name
        }
        
        func getPerformance() -> String {
            return "The album \(name) sold lots"
        }
    }
    
    class StudioAlbum: Album {  // 상속
        var studio: String
        
        init(name: String, studio: String) {
            self.studio = studio
            super.init(name: name)
        }
        
        override func getPerformance() -> String {
            return "The studio album \(name) sold lots"
        }
    }
    
    class LiveAlbum: Album {  // 상속
        var location: String
        
        init(name: String, location: String) {
            self.location = location
            super.init(name: name)
        }
        
        override func getPerformance() -> String {
            return "The live album \(name) sold lots"
        }
    }
    
    var taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studios")
    var fearless = StudioAlbum(name: "Speak Now", studio: "Aimeeland Studio")
    var iTunesLive = LiveAlbum(name: "iTunes Live from SoHo", location: "New York")
    
    var allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]
    
    for album in allAlbums {
        print(album.getPerformance())  // 다형성에 의해 오버라이딩된 함수 호출
    }

# 타입캐스팅

오브젝트의 실제 타입 이 바뀌는 것이 아니라 스위프트가 생각하는 해당 오브젝트의 타입 이 바뀌는 것!

as?

  • 옵셔널 다운캐스팅 연산자로 다운캐스팅 성공 시 옵셔널, 실패 시 nil 반환
  • 추출 필요
    for album in allAlbums {
        print(album.getPerformance())
        
        if let studioAlbum = album as? StudioAlbum {
            print(studioAlbum.studio)
        } else if let liveAlbum = album as? LiveAlbum {
            print(liveAlbum.location)
        }
    }
  • 배열 반복문에서 다운캐스팅을 할 수도 있음
  • nil 이 존재하는 경우를 대비해 nil coalescing 필요!
for album in allAlbums as? [LiveAlbum] ?? [LiveAlbum]() {  // 다운캐스팅 실패 시 빈 배열 반환
        print(album.location)
    }

as!

  • 강제 다운캐스팅 으로 타입캐스팅 실패 시 에러 발생
for album in allAlbums {
    let studioAlbum = album as! StudioAlbum
    print(studioAlbum.studio)
}

# 이니셜라이저를 통한 타입 변환

  • 내장 타입의 일부는 아래와 같은 방식으로 타입 변환이 가능
let number = 5
let str = String(number)
print(str)  // "5"

☀️ 느낀점

  • enum 이 지금까지 다른 언어들과 달라서 좀 헷갈렸는데 나만의 타입 을 만드는 거라고 생각하니까 조금 감이 오는 것 같기도..하고...아닌 것 같기도...
  • 클로저를 내가 직접 만들 일은 거의 없다니 매우 다행이다...클로저 파트는 아예 다시 읽었는데 아직도 어렴풋한 느낌...
profile
☀️

0개의 댓글