여태까지 자주 사용해왔지만 인지하지 못하고 있었던 Generics!!
먼저 뷰모델 만들어주고 어떤 뉘앙스로 흘러가는 지 살펴봅시다
저기 뷰에서 .onTapGesture일 때 array의 아이템을 다삭제해주는 메소드를 작성했는데 지금 이 메소드는 타입에 상관없잖음!!
dataArray가 [String]이든 다른 모델 타입이든 상관없이 다 동작함!!
append도 마찬가지죠
자 다른 예시를 봅시다
String이라는 모델을 만들어줌
info라는 String? 프로퍼티가 있고
removeInfo는 StringModel의 info에 nil을 넣어주게 됨
(지금처럼 한줄에 반환타입이 명시되어 있으면 return 생략 가능하죠!)
struct StringModel {
let info: String?
func removeInfo() -> StringModel {
StringModel(info: nil)
}
}
class GenericsViewModel: ObservableObject {
@Published var stringModel = StringModel(info: "Hello, world!")
func removeData() {
stringModel = stringModel.removeInfo()
}
}
struct GenericsBootcamp: View {
@StateObject private var vm = GenericsViewModel()
var body: some View {
VStack {
Text(vm.stringModel.info ?? "no data")
.onTapGesture {
vm.removeData()
}
}
}
}
요렇게 모델 뷰모델 뷰가 다 있어요
아까랑 마찬가지로 removeData를 하게 되는데
지금 보면 vm.removeData() 메소드가 stringModel만 바꿔서 동작하게 되잖음
이거 어떻게 Generic하게 쓸 수 있을까!
boolModel을 만들어서 또 똑같이 구현했는데 귀찮잖음
꺽쇠로 타입을 적어주면 Generic 타입이 된다!
똑같죠!
보통 GenericType은 T로 표시합니다~
요로코롬 말이죠
일반적으로 사용하는 거랑 조금 다릅니다
요렇게 있는데 요 뷰에서 subView처럼 다른 걸 받는다고 가정해보자
그냥 View로 작성하면 안된다는 에러가뜸
Any View로 작성할 수도 있지만 퍼포먼스에도 영향을 주고,
읽기에도 어려움
CustomType이란 genericType을 작성해줬는데 또 에러가 뜬다!
content가 View가 되려면 View를 준수해야하기 때문임
요렇게 GenericType에 View프로토콜을 준수하고 있는 애들만 들어오게 해주면 에러가 사라지게 됩니다~
그러고 확인해보면~
GenericView의 프로퍼티 content에 View를 넣을 수가 있죠!
T로 수정해주면
뙇 GenericView 완성~~