Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
SwiftUI/SwiftUI(Intermediate)

0. Identifiable / Hashable

by Toughie 2023. 5. 20.

⭐️Identifiable / Hashable⭐️



코딩하다 보면 자주 만나는(채택하는 경우가 많은) Identifiable, Hashable 프로토콜에 대해 정리해보자.

Identifiable Protocol


'식별 가능한 타입'

채택한 타입은 고유한 식별자를 가지고 있어야함. (id)

id는 유니크한 값을 가지는 속성임.

컬렉션/테이블 뷰 등에서 데이터의 각 항목을 식별하기 위해 프로토콜이 요구됨.

//  Created by Toughie on 2023/05/20.
//

import SwiftUI

struct MyModel: Identifiable {
    let id = UUID().uuidString
    let title: String
}

struct IdentifiablePrac: View {
    
    let data: [MyModel] = [
        MyModel(title: "One"), MyModel(title: "Two"), MyModel(title: "Three"),
        MyModel(title: "Four"), MyModel(title: "Five")
    ]
    
    var body: some View {
        ScrollView {
            ForEach(data) { item in
                VStack(spacing: 50) {
                    Text(item.title)
                        .font(.headline)
                    Text(item.id)
                }
            }
        }
    }
}

여기서 UUID().uuidstring은 ?

Universally Unique Identifier를 생성하는 방법 중 하나.

128비트의 값으로 랜덤하게 생성되는 고유한 식별자를 나타내는 타입임. -> 데이터의 고유성 보장/ 객체 식별 가능.

UUID().uuidstring은 새로운 UUID를 생성 후 해당 UUID를 문자열 형태로 반환함. (36자리 형식)

 

Hashable Protocol

'해시 가능한 타입'

-> 해시 함수를 사용해서 고유한 해시 값을 생성. 

해시 함수는 임의의 크기를 가진 입력 데이터를 고정된 크기의 해시값으로 매핑하는 함수임.

해시값은 고유한 식별자로 사용되며, 일반적으로 정수 형태로 표현됨.

Hashable 타입은 같은 값에 대해 항상 동일한 해시값을 반환해야함.

(Swift에서 Set나 Dictionary와 같은 컬렉션은 내부적으로 해쉬값을 사용해 요소의 고유성을 확인하거나,
요소에 접근하기 위해 해쉬함수를 사용함_빠른 검색 가능_)

 

//  Created by Toughie on 2023/05/20.
//

import SwiftUI

struct MyModel: Hashable {
    
    let title: String
    
    //따로 구현하지 않으면 자동으로 hash 함수가 구현됨.
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
    }
}


struct HashablePrac: View {
    
    let data: [MyModel] = [
        MyModel(title: "One"), MyModel(title: "Two"), MyModel(title: "Three"),
        MyModel(title: "Four"), MyModel(title: "Five")
    ]
    //String은 Hashable 프로토콜을 채택
    //아래에서 각각의 아이템은 해쉬값을 가짐
    
    var body: some View {
        ScrollView {
            VStack(spacing: 50) {
                ForEach(data, id: \.self) { item in
                    VStack {
                        Text(item.title)
                            .font(.headline)
                        Text(item.title.hashValue.description)
                    }
                }
            }
        }
    }
}

Hashable 프로토콜을 준수하는 Swift의 기본 타입.
Int, String, Double, Bool

 

컬렉션 타입의 요소들은 Hashable 프로토콜을 준수해야함.

Array<Int>, Set<String>, Dictionary<String, Double>

 

 

+ ForEach 루프 내에서 data가 Identifiable인 경우와 Hashable인 경우의 차이는?

Identifiable인 경우

Identifiable을 채택한 타입의 id(고유한 식별자) 속성을 통해 요소간의 고유성 확인. 

 

Hashable인 경우

요소들의 해시값을 기반으로 구분함.

 

struct ContentView: View {
    let strings = ["Apple", "Banana", "Cherry"]

    var body: some View {
        List(strings, id: \.self) { string in
            Text(string)
        }
    }
}

위 예시에서는 데이터인 strings가 Hashable 프로토콜을 준수하는 타입이다. (String은 Hashable을 채택하는 기본 타입)

즉 배열 내 문자열들은 각각 고유한 해시값을 가지며, 각각의 문자열 그 자체로 고유하게 식별될 수 있다.

\.self는 각 요소를 자기 자신으로 식별하라는 의미임.