SwiftUI) ForEach (feat. forEach(_:)) 톺아보기 02 | change-challenge

장호진·2023년 4월 17일
0

swift

목록 보기
3/3
post-thumbnail
struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable

우리는 전 블로그을 통해

  1. forEach(:_)와 ForEach의 차이점
  2. ForEach 프로토타입을 보면서 아래와 같은 특징들을 찾았다.

[ 구조체 ForEach의 특징 ]
1️⃣. <Data, ID, content>
2️⃣. where Data: RandomAccessCollection, ID : Hashable
3️⃣. RandomAccessCollection (랜덤 엑세스 콜렉션)
4️⃣. Hashable (해쉬블)

자, 이제는 ForEach의 예시를 통해 어떻게 사용했는 지 확인해보자!


🔥 ForEach 예문

애플 공식 홈페이지에 나와있는 예문으로 돌아가보자.

UI 실행은 위와 같이 된다.
이것의 예시 코드는 아래와 같다.

Section(header: Text("Attendees")) {
                ForEach(scrum.attendees) { attendee in
                    Label(attendee.name, systemImage: "person")
                }
            }

⭐️ 이 때 드는 의문이 있다.⭐️

  1. 구조체인데 무슨 메소드처럼 적으면 실행이 되는 것이냐?
    (forEach(:_)랑 툭 까놓고 다르지 않네?)
  2. scrum.attendees의 Type은 어떻게 될까?
    (RandomAccessCollection하고, Hashable하는가)

의문을 하나 하나 풀어나가보자!


❓ 구조체인데 무슨 메소드처럼 적으면 실행이 되는 것이냐?

이때 짚고 넘어가야할 점은
C/C++에 익숙해있다보면 도대체 왜 구조체를 생성하였는데 View가 만들어지지? 라고 생각하기 쉬운데, SwiftUI에서 List처럼 View를 만들어주는 View Container역할을 하는 구조체라고 생각해야한다.

공식문서를 보면 List도 모두 Structure 되어있다.

이름은 forEach(:_)와 비슷하기에 반복문이라고 생각하기 쉬운데,
그런 의도로 이름을 그렇게 지은 듯 하지만 내부 Data를 기반으로 View를 계산해서 보여주는 것이다.

애플 공식문서 ForEach 안에 다양한 init가 있고, 이 중에 하단의 init을 사용하여 실행되었다.


❓ scrum.attendees의 Type은 어떻게 될까?
(RandomAccessCollection하고, Hashable하는가)

ForEach(scrum.attendees) { attendee in
	Label(attendee.name, systemImage: "person")
}

다시 위의 예시를 보면서 이야기를 하면,

첫번 째 인자로 Datascrum.attendees이 된 것이고,
두번 째 인자로서 ((Data.Element) -> Content) 클로저

{ attendee in
	Label(attendee.name, systemImage: "person")
}

를 받은 것이다.

그러면 scrum.attendees가 어떤 Type인 지 보자.
Data은 Hashable 프로토콜을 채택해야한다.

위에 SwiftUI 예제에서 scrum.attendeesvar attendees: [Attendee] 이다.

scrum.attendeesArray이기에 RandomAccessCollection를 충족한다.

다음 조건은 충족하는 가?

Hashable이 아니라 Identifiable 프로토콜을 채택하였다??

-> Identifiable 프로토콜은 내부적으로 Hashable 프로토콜을 채택하고 있기 때문에, Identifiable 프로토콜을 사용하는 경우에는 ID 타입이 Hashable 프로토콜을 채택하면 된다.

그렇다고 ID는 Hashable 프로토콜을 채택하지 않았는데??

-> Identifiable 프로토콜을 채택한 객체에서 ID 타입은 Hashable 프로토콜을 채택해야 하지만, 이를 구현할 때 UUID 타입을 사용할 수 있습니다. Identifiable 프로토콜을 채택한 객체에서 ID 타입을 UUID 타입으로 지정하여 구현하면, 이를 사용하는 SwiftUI의 List나 ForEach와 같은 뷰에서도 모델의 고유성을 보장할 수 있다고 한다.

Identifiable 프로토콜은 각 데이터가 각자를 식별할 수 있는 무언가를 가지고 있는 경우에 충족한다고 볼 수 있다.

scrum.attendeesIdentifiable를 충족한다.


마치면서

이를 통해 ForEach가 어떤 Data를 충족하는 지 확인해보았다.
ForEach를 쓰는데 도대체 Hashable과 Identificable을 어떻게 처리해야하나 고민했는데 조금 더 수월하게 사용할 수 있지 않을까 싶다.
애플 스유 Documentation을 그냥 슬렁 슬렁 넘어가면 그냥 타자연습 밖에 안되지만 하나 하나 뜯어보면 분명 더 많이 얻을 수 있을 것 같다.

profile
도전하고, 바꾸고

0개의 댓글

관련 채용 정보