Swift - 인스턴스 생성 및 소멸

인스턴스 생성

  • 저장 프로퍼티의 초깃값을 설정하는 일을 수행.
  • 이니셜라이저를 정의하면 초기화 과정을 직접 구현 가능.

    이니셜라이저는 새로운 인스턴스를 생성할 수 있는 특별한 메서드, 인스턴스의 첫 사용을 위해 초기화하는 용도이며 반환 값은 없습니다.

class Student {
    init() {
        // 초기화 코드
    }
}

struct Lecture {
    init() {
        // 초기화 코드
    }
}

enum Major {
    case computerScience

    init() {
        // <b>열거형은 반드시 케이스 중 하나로 초기화 되어야 합니다.</b>
        self = .computerScience
    }
}

프로퍼티 기본값

  • 구조체와 클래스의 인스턴스는 처음 생성될 때 옵셔널 저장 프로퍼티를 제외한 모든 저장 프로퍼티에 적절한 초깃값이 할당되어야 합니다.
  • 초기화 후에 값이 확정되지 않은 저장 프로퍼티는 존재할 수 없습니다.

이니셜라이저로 저장 프로퍼티에 초깃값 설정

struct Volume {
    var size: Double

    init() {
        size =  0.0 // size의 초깃값 할당
    }
}

let volume: Volume = Volume()
print(volume.size) // 0.0

저장 프로퍼티에 초깃값을 설정

struct Volume {
    var size: Double = 0.0
}

let volume: Volume = Volume()
print(volume.size) // 0.0

이니셜라이저도 매개변수를 가질 수 있습니다. 인스턴스를 초기화하는 과정에서 필요한 값(argument, 인수)을 전달하여 초기화할 수 있습니다.

옵셔널 프로퍼티 타입

  • 인스턴스가 사용되는 동안에 값을 꼭 가지지 않아도 되는 저장 프로퍼티가 있을 경우 사용.
  • 초기화되는 과정에서 값을 지정해주기 어려운 경우, 저장 프로퍼티를 옵셔널로 선언합니다.
class Person {
    let name: String // 상수 프로퍼티
    var age: Int?

    init(name: String) {
        // <b>상수 프로퍼티는 초기화 과정에서만 값이 할당 될 수 있습니다.</b>
        self.name = name

    }
}

기본 이니셜라이즈, 멤버와이즈 이니셜라이저

  • 기본 이니셜라이저는 프로퍼티의 기본값으로 프로퍼티를 초기화해서 인스턴스를 생성.
    • 저장 프로퍼티의 기본값이 모두 지정되어 있고, 동시에 사용자 정의 이니셜라이저가 정의되지 않아야합니다.
  • 구조체는 사용자정의 이니셜라이저르 구현하지 않으면 프로퍼티의 이름으로 매개변수를 가지는 이니셜라이저인 멤버와이즈 이니셜라이저를 기본으로 제공.

초기화 위임

값 타입인 구조체와 열거형은 코드의 중복을 피하기 위하여 이니셜라이저가 다른 이니셜라이저에게 일부 초기화를 위임하는 초기화 위임을 간단하게 구현할 수 있습니다. (초기화 위임은 최소 두 개 이상의 사용자 정의 이니셜라이저가 필요합니다.)

enum Student {
    case elemantary, middle, high
    case none

    init() {
        self = .none
    }

    init(KoreanAge: Int) {
        switch KoreanAge {
            case 8...13:
                self = .elemantary
            case 14...16:
                self = .middle
            case 17...19:
                self = .high
            default:
                self = .none
        }
    }

    init(bornAt: Int, currentYear: Int) {
        // self.init으로 사용자 정의 이니셜라이저로 초기화를 위임.
        self.init(KoreanAge: currentYear - bornAt + 1)
    }
}

실패 가능한 이니셜라이저(Failable initializer)

클래스, 구조체, 열거형에 모두 정의할 수 있으며 실패했을 때 nil을 반환합니다. init 키워드 대신 init? 키워드를 사용합니다.

실패 가능한 이니셜라이저가 특정 값을 반환하지는 않습니다. return nil(실패), return(성공)으로 성공과 실패를 표현할 뿐입니다.

enum Student {
    case elemantary, middle, high

    init?(KoreanAge: Int) {
        switch KoreanAge {
            case 8...13:
                self = .elemantary
            case 14...16:
                self = .middle
            case 17...19:
                self = .high
            default:
                // 초기화 실패를 표현
                return nil
        }
    }

    init?(bornAt: Int, currentYear: Int) {
        self.init(KoreanAge: currentYear - bornAt + 1)
    }
}

함수를 사용한 프로퍼티 기본값 할당

  • 사용자정의 연산을 통해 저장 프로퍼티 기본값을 설정할 때 클로저나 함수를 사용.

    클로저를 사용하여 프로퍼티 기본값을 설정할 때, 실행 시점은 이니셜라이즈(초기화)입니다. 따라서 다른 프로퍼티의 값이 세팅되기 전이기에 다른 프로퍼티를 사용하여 연산할 수 없습니다.

struct Student {
    var name: String?
    var number: Int?
}

class SchoolClass {
    var student: [Student] = {
          // 새로운 인스턴스를 생성하고 사용자정의 연산을 통한 후 반환해줍니다.
          // 반환되는 값의 타입은 [Student] 타입이어야 합니다.

          var arr: [Student] = [Student]()

          for num in 1...15 {
              var student: Student = Student(nam: nil, number: num)
              arr.append(student)
          }

          return arr
      }()
}

인스턴스 소멸

  • 클래스의 인스턴스는 디이니셜라이저(Deinitializer)를 구현할 수 있습니다. 디이니셜라이저는 인스턴스가 메모리에서 해제되기 직전 클래스 인스턴스와 관련하여 원하는 정리 작업을 구현할 수 있습니다.
  • deinit 키워드를 사용하며, 클래스의 인스턴스가 메모리에서 소멸되기 바로 직전에 호출됩니다.
  • 스위프트는 인스턴스가 더이상 필요하지 않으면 자동으로 메모리에서 소멸시킵니다.(ARC)
  • 인스턴스 내부에서 외부 리소스를 사용했다면, 인스턴스가 소멸하기 직전에 파일을 다시 저장하고 닫아주는 등의 부가 작업이 필요한 경우에 유용하게 사용합니다.

글의 일부 내용은 야곰님의 저서 스위프트 프로그래밍(2017, 한빛미디어)를 참고하여 작성되었습니다.