SwiftUI vs UIKit: Initializer 차이점

윤지하·2025년 8월 13일
0

swift

목록 보기
1/9

iOS 개발을 하다 보면 SwiftUI와 UIKit의 초기화(Initialization) 방식이 크게 다르다는 것을 알게 됩니다. 오늘은 이 차이점과 그 이유에 대해 자세히 알아보겠습니다.

📱 문제 상황

SwiftUI에서 View를 만들 때 init을 작성하지 않아도 되는데, UIKit에서는 반드시 작성해야 합니다. 왜 이런 차이가 있을까요?

🔍 핵심 차이점: Memberwise Initializer

SwiftUI (Struct 기반)

struct PartAddView: View {
    let project: Project
    let viewModel: PartListViewModel
    @Binding var isPresented: Bool
    
    // ✅ init 자동 생성! 작성할 필요 없음
    
    var body: some View {
        Text("Hello, SwiftUI!")
    }
}

// 사용할 때
PartAddView(
    project: myProject,
    viewModel: myViewModel,
    isPresented: $showModal
)

UIKit (Class 기반)

class PartAddViewController: UIViewController {
    let project: Project
    let viewModel: PartListViewModel
    
    // ❌ 반드시 init을 직접 작성해야 함!
    init(project: Project, viewModel: PartListViewModel) {
        self.project = project
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }
    
    // 스토리보드 지원을 위한 필수 구현
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

🤔 왜 이런 차이가 발생할까?

1. Class vs Struct의 근본적 차이

구분UIKit (Class)SwiftUI (Struct)
타입참조 타입 (Reference Type)값 타입 (Value Type)
상속가능 ✅불가능 ❌
초기화복잡 (상속 체인 고려)단순 (독립적)
메모리Heap 할당Stack 할당

2. Swift의 자동 Memberwise Initializer 규칙

Swift는 struct에 한해서 다음 조건을 만족하면 자동으로 initializer를 생성합니다:

  • ✅ Struct여야 함
  • ✅ 커스텀 initializer가 없어야 함
  • ✅ 모든 stored property가 기본값이 없거나, 접근 가능해야 함
// 자동 생성 예시
struct Person {
    let name: String
    var age: Int
}

// Swift가 자동으로 생성하는 init
// init(name: String, age: Int)

let person = Person(name: "김철수", age: 30)  // ✅ 작동!

3. UIViewController의 특수성

UIViewController는 복잡한 생명주기와 초기화 과정을 가집니다:

class CustomViewController: UIViewController {
    let data: String
    
    init(data: String) {
        self.data = data
        // 1️⃣ 반드시 super.init 호출 필요
        super.init(nibName: nil, bundle: nil)
        
        // 2️⃣ super.init 이후에 추가 설정 가능
        setupUI()
    }
    
    // 3️⃣ 스토리보드/XIB 지원을 위한 필수 구현
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 4️⃣ 생명주기 메서드들
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

💡 실제 개발에서의 차이

SwiftUI의 간결함

// View 정의
struct ProfileView: View {
    let user: User
    let isEditable: Bool
    @Binding var isPresented: Bool
    
    var body: some View {
        // UI 구현
    }
}

// 사용 - 매우 간단!
ProfileView(
    user: currentUser,
    isEditable: true,
    isPresented: $showProfile
)

UIKit의 보일러플레이트

// ViewController 정의
class ProfileViewController: UIViewController {
    let user: User
    let isEditable: Bool
    weak var delegate: ProfileDelegate?
    
    init(user: User, isEditable: Bool) {
        self.user = user
        self.isEditable = isEditable
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// 사용 - 더 많은 코드 필요
let profileVC = ProfileViewController(
    user: currentUser,
    isEditable: true
)
profileVC.delegate = self
navigationController?.pushViewController(profileVC, animated: true)

🛠 UIKit에서 코드 줄이는 팁

1. Protocol Extension 활용

protocol StoryboardInstantiable {
    static var storyboardName: String { get }
}

extension StoryboardInstantiable where Self: UIViewController {
    static func instantiate() -> Self {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        return storyboard.instantiateViewController(withIdentifier: String(describing: self)) as! Self
    }
}

2. Factory 패턴 사용

extension UIViewController {
    static func create<T: UIViewController>(
        configure: (T) -> Void = { _ in }
    ) -> T {
        let viewController = T()
        configure(viewController)
        return viewController
    }
}

// 사용
let vc = ProfileViewController.create { vc in
    vc.user = currentUser
    vc.isEditable = true
}

📊 비교 요약

특징SwiftUIUIKit
초기화 코드자동 생성수동 작성
코드량적음많음
유연성제한적높음
학습 곡선낮음높음
커스터마이징제한적자유로움
레거시 지원iOS 13+iOS 2.0+

🎯 결론

SwiftUI의 자동 memberwise initializer는 개발자의 생산성을 크게 향상시킵니다. 하지만 이것은 struct의 단순함 덕분에 가능한 것이며, UIKit의 class 기반 아키텍처에서는 더 복잡한 초기화 과정이 필요합니다.

각 프레임워크는 서로 다른 철학과 목적을 가지고 설계되었습니다:

  • SwiftUI: 선언적, 간결함, 빠른 개발
  • UIKit: 명령형, 세밀한 제어, 완전한 커스터마이징

프로젝트의 요구사항과 타겟 iOS 버전에 따라 적절한 프레임워크를 선택하는 것이 중요합니다.

🔗 참고 자료


이 글이 도움이 되셨다면 좋아요와 공유 부탁드립니다! 질문이나 의견은 댓글로 남겨주세요.

profile
성장하고 싶은 개발자

0개의 댓글