본문 바로가기

야곰커리어캠프_TIL

20200211 / D5 / 인스턴스 끼리 값할당 시 주의사항(feat. 옵셔널체이닝)

struct Book {
    let title: String
    let genre: Genre?
    let bookCode: Int
    var inventory: Int?
}

struct Genre {
    let novel: String
    let selfDeveloping: String
    let economy: String
    let finance: Finance?
}

struct Finance {
    let A: String? = "안녕클래오 파트라"
    let B: String? = "세상에서 제일가는"
    let C: String? = "포테이토 칩"
    let vestStockAndVestTiming: String? = "최고의 주식 최적의 타이밍"
}

let book: Book? = Book(title: "최고의 주식 최적의 타이밍", genre: bookGenre, bookCode: 1234, inventory: 1)
let bookGenre: Genre? = Genre(novel: "소설", selfDeveloping: "자기계발", economy: "경제", finance: financeBook)
let financeBook: Finance? = Finance()

if let unwrappedBook = book {
    if let unwrappedGenre = unwrappedBook.genre {
        if let financeBook = unwrappedGenre.finance?.vestStockAndVestTiming {
            print("Optional Binding : \(financeBook)")
        }
    }
}
// 만일 옵셔널타입에 값이 포함되 있으면 프로퍼티나 메서드 혹은 서브스크립트를 호출하고 만약 값이 nil이거나 없을 경우 nil을 반환한다.
if let bookTitme = book?.genre?.finance?.vestStockAndVestTiming {
    print("Optional Chaining : \(bookTitme)")
}

 

옵셔널 체이닝을 학습해보는 예제를 만들어보았다. 간단하게 좋아하는 책을 찾으러 접근하는데 이상하게 값이 확인이 되질 않는다..?

 

?????

왓 헤픈,,,?

lldb를 켜서 확인해보자

현재 lldb는 34번줄에 위치해 있다. 그런데 financeBook은 인스턴스화가 되었는데 왜 po bookGenre?.finnance?.vestStockAndVestTiming으로 입력했을때 nil이나올까 ????

34번줄의 print()문으로 출력한 financeBook?.vestStockAndVestTiming은 잘만나오는데,,, ????

 

인스턴스값을 초기화되기 이전의 값으로 할당했을 경우(비정상)

 

인스턴스값을 초기화된 후의 값으로 할당했을 경우(정상)

 

그런데 왜 financeBook은 값인 초기화된값으로 잘 나올까 ???

 

그 이유는 bookGenre?.finance 안에 초기화 되기전의 financeBook 인스턴스 값을 할당하여 그렇게 나오는것이다.

초기화된 이후에도 이미 값을 할당한건 초기화이전의 값을 할당했기때문에 계속 nil이 나오는것이다.

(그럼 옵셔널타입의 인스턴스는 초기화되기 전에는 모두 nil값인가 ?)

 

정상적인 인스턴스화 이후에는 정상적인 호출이 되고 있는걸 볼 수 있다.

 

 

결론

인스턴스화 할때 위에서부터 타입을 정의한 순서대로 인스턴스를 생성할 것이아니라. 오히려 반대로 생성을 해주어야한다는것이다. 정확히는 값을 할당해야할 인스턴스 부터  생성해주는 것이 순서가 맞는 것같다.

예시) 옵셔널 체이닝을 해주기위해서 인스턴스로 접근하는 타입 순서는 Book -> Genre -> Finance 인데 그렇게되면 초기화되기 이전의 값을 할당해주기때문에 반대로 해줘야한다. 이 부분을 주의하자