SwiftUI는 UIKit과 다르게 모든 뷰가 Struct로 선언되어 있다.
왜 그렇게 해야하며, 그렇게 설계한 이유가 궁금해서 공부하게 되었다.
먼저 염두해야하는 내용은 SwiftUI는 선언형 프로그래밍이라는것이다!
함수형프로그래밍은 선언형 프로그래밍의 좀더 좁은 범위다.
그러면 늘 그렇듯 먼저 알아야하는 내용에 대해서 공부하자.
구조체와 클래스의 차이점
먼저 구조체와 클래스의 차이는 다음과 같다.
1.
상속 가능여부
클래스는 상속이 가능하지만, 구조체는 상속이 불가능하다.
2.
형식의 차이
클래스는 참조타입이지만, 구조체는 값 타입이다.
구조체는 메모리영역에서 stack영역에 저장이 되며, 클래스는 참조타입이기 때문에 heap영역에 저장이 된다.
값타입의 구조체는 값을 변경하려고 하면, 새로운 메모리를 할당하고 값을 복사해서 새로운 값을 생성하게 되는데, 클래스는 같은 메모리 주소를 참조하기 때문에 값을 변경하면 모든 참조가 그 값을 바라보게 된다. 즉 해당 값을 바꿔버린다.
또한 스택은 메모리에 올라갔다가 사용이 종료되면 바로 삭제가 되지만, 힙에 올라간 코드는 가비지컬렉터에 의해서 정리를 하게 된다.
특히 기존의 uikit개발에서는 ARC를 사용해서 가비지컬렉팅을 하게 되는데 강한 상호참조가 일어나면 메모리릭이 일어나는 가능성이 높앗다. 이를 위해서 약한 참조를 하는 경우가 생겼다.
즉 정리를 하자면 클래스보다 구조체의 이점은 다음과 같다.
•
구조체는 클래스 보다 빠르다.
•
메모리릭으로 부터 안전하다.
•
또한 참조타입이 아니기 때문에 사이드이팩트에서 안전하다
는 결론이 나온다.
Swift에서는 클래스보다 Struct로 선언하는것을 추천한다.
스위프트에서 추천하는 struct와 class에서 고민할때 가이드라인이다.
기본적으로 struct를 추천하고 있다.
이유는 다음과 같다.
구조체를 이용하면, 앱전체의 상태를 고려할 필요없이 코드를 이해하기 쉽다.
구조체는 값 타입이기 때문에 변경사항이 다른 부분에서 참조를 통해서 변경되지 않기 때문에 명시적으로 흐름을 전달하지 않는 이상 이루어지지않는다.
즉 사이드 이팩트로 부터 안전하고 좀더 편하게 코드의 흐름을 이해할수 있기 때문이다.
SwiftUI에서 뷰를 Struct로 선언하는 이유
위에서 말했던 구조체가 클래스보다 좋은 이유는 다음과 같다.
1.
성능
2.
가변성의 최소화
3.
메모리릭의 안전성
1. 성능
구조체는 클래스와 다르게 스택 메모리를 사용하게 되며 빠르다.
또한 상속을 하지 않는다. 기존 UIkit은 상속을 사용하게 되며, 거의 대부분의 뷰는 UIView를 상속하고 있는데, UIView는 굉장히 많은 프로퍼티와 메소드의 집합이다. 이를 상속하게 되면, 엄청난 수의 프로퍼티와 메소드를 가져가야 한다는 뜻이다.
이를 구조체로 만드는 것으로 상속하지 않기 때문에 성능이 굉장히 향상된다.
•
그렇다면 뷰의 상속을 어떻게 해결할까???? ⇒ ViewModifier로 해결하였다.
2. 가변성의 최소화
구조체는 참조타입이 아닌 값 타입이기 때문에 외부에서 값에 접근하여 해당 값이 변경될 일이 없다.
이는 함수형프로그래밍에서 굉장히 중요시하는 “사이드이펙트” 가 없는 코드가 된다.
3. 메모리릭에서부터의 안전성
기존의 UIkit에서의 참조타입은 강한상호참조가 일어나는것으로 부터 메모리릭이 많이 발생하고 또한 이러한 위험이 존재한다.
하지만 SwiftUI에서는 값타입인 구조체를 사용하는것으로 이러한 강한상호참조가 일어나지 않기 때문에 메모리릭으로부터 상대적으로 안전하다.
정리
SwiftUI는 가볍게 만들려고 한것 같다.
기존의 UIKit에서 UIView의 상속을 해야 했으며 이는 굉장히 많은 프로퍼티와 메소드를 내포하고 있어햐 했다.
또한 ARC와 어플리케이션 주기에 관련해서 좀더 자유롭게 설계하려고 하였다.
이를 적용하기 위해서 값타입인 구조체를 사용하였다.
값타입을 통해서 코드 어디에서나 속성을 변경할수 있으며, 자체 책임을 가지고 있게 된다.
뷰가 서로 독립적으로 격리되어 있으며, 이를 통해 특정 보기에 대한 변경 사항은 공통 소스에 의해 구속되지 않는 한 다른 보기에 영향을 미치지 않는다.
결과적으로 애플은 선언적 프로그래밍을 만들고 싶었으며, 이를 위해서 사이드 이펙트가 없으며, 빠르고, 가볍기 때문에 클래스 대신 구조체를 통해서 뷰를 생성한 것이라고 생각한다.
참고자료