8.1.4 초기화

구조체의 초기화

구조체나 클래스 이름 뒤에 빈 괄호를 붙이면 기본적인 인스턴스가 만들어진다고 설명했습니다. 필요에 따라 빈 괄호가 아니라 인자값을 넣어주기도 하는데, 이때 입력되는 인자값들은 대부분 객체의 프로퍼티를 초기화하기 위해 반드시 필요한 값들입니다.

스위프트에서 옵셔널 타입으로 선언되지 않은 프로퍼티는 명시적으로 초기화해 주어야 합니다. 초기화되지 않은 프로퍼티가 있으면 컴파일 오류가 발생합니다. 명시적인 초기화란 두 가지 경우 중 하나를 의미합니다.

  1. 프로퍼티를 선언하면서 동시에 초기값을 지정하는 경우

  2. 초기화 메서드 내에서 프로퍼티의 초기값을 지정하는 경우

이것이 의미하는 바는 클래스, 구조체의 모든 프로퍼티는 적어도 인스턴스가 생성되는 시점까지는 반드시 초기화되어야 한다는 것입니다. 위 두 가지가 아니라면 옵셔널 타입으로 선언되어 자동으로 nil을 할당받게 해야 합니다.

구조체는 모든 프로퍼티의 값을 인자값으로 입력받아 초기화하는 기본 초기화 구문을 자동으로 제공합니다. 프로퍼티를 보통 멤버 변수라고 부르므로, 이 초기화 구문을 '멤버와이즈 초기화 구문'(Memberwise Initializer)라고 부르기도 합니다.

// width와 height를 매개변수를 하여 Resolution 인스턴스를 생성
let defaultRes = Resolution(width: 1024, height: 768)

앞에서 구조체로 정의한 Resolution의 멤버와이즈 초기화 구문입니다. 이 구문은 Resolution 구조체가 가지고 있는 두 개의 프로퍼티 width, height를 초기화하기 위한 인자값을 입력받아, 내부적으로 프로퍼티를 초기화합니다.

print("width : \(defaultRes.width), height : \(defaultRes.height)")

// 실행 결과
width : 1024, height : 768

이처럼 멤버와이즈 초기화 구문은 인스턴스를 생성하는 형식을 정의할 뿐 아니라, 입력된 인자값을 이용하여 프로퍼티를 초기화하는 과정까지 알아서 처리합니다.

멤버와이즈 초기화 구문 외에도 구조체의 인스턴스를 생성할 때 사용할 수 있는 초기화 구문은 하나가 더 있습니다. 최초에 Resolution 인스턴스를 만들 때 사용했던, 빈 괄호 형식입니다. 이 초기화 구문은 아무 인자값도 입력받지 않으며, 따라서 어떤 프로퍼티도 초기화하지 않습니다. 단순히 구조체의 인스턴스를 생성하는 역할만 할 뿐입니다. 따라서 이 형식의 초기화 구문을 사용하려면, 객체의 모든 프로퍼티는 선언과 동시에 초기값이 지정되어 있어야 합니다.

클래스의 초기화

클래스는 구조체와 달리 멤버와이즈 형식의 초기화 구문이 제공되지 않습니다. 클래스에서 제공하는 것은 빈 괄호 형태의 기본 초기화 구문뿐입니다. 만약 초기화되지 않은 프로퍼티가 있다면 기본 초기화 구문은 사용할 수 없으며, 이 때에는 직접 초기화 구문을 정의해서 내부에서 해당 프로퍼티를 초기화해 주어야 합니다. 물론 모든 프로퍼티의 초기값을 지정했다면 별도의 초기화 구문을 정의할 필요는 없습니다. 클래스의 초기화에 대해서는 아래 두 원칙을 지키는 게 좋습니다

  1. 모든 프로퍼티는 정의할 때 초기값을 주던가, 아니면 옵셔널 타입으로 선언한다.

  2. 인스턴스를 생성할 때에는 클래스명 뒤에 ()를 붙여준다.

프로퍼티와 초기화 구문에 대해 명확한 이해가 생기기 전까지는 위의 두 원칙을 지키는 게 좋습니다.

Last updated