Swift - Initialization(Failable Initializer)

이원석·2024년 11월 27일

Swift

목록 보기
22/38

Failable Initializers

기존 생성자(Nonfailable Initializers)는 컴파일 시점에 모든 프로퍼티가 초기화 되어야 하기 때문에 초기화에 실패할 경우, 컴파일 에러가 발생한다. 하지만 Failable Initializers는 초기화에 실패하더라도 에러가 발생하지 않고 nil을 리턴한다.
생성자의 Optional 버전이라고 볼 수 있다.

  • 실패할 가능성이 있는 초기화일 경우 사용(ex. 형 변환)
  • 초기화에 실패할 경우 nil 리턴
  • Optional 생성자라고 부를 만큼 리턴 받은 인스턴스의 타입은 무조건 옵셔널 타입

init?

초기화에 성공하면 초기화된 인스턴스가 Optional Type으로 리턴
초기화에 실패하면 nil리턴

init?(){ ... }

init!

초기화에 성공하면 초기화된 인스턴스가 (특정 조건일 때) Non-Optional Type으로 리턴
옵셔널 강제 추출이기 때문에, 초기화 실패 시 크래시 발생

class Human{
	let name: String
    
    init?() {
        self.name = "unknown"
    }

    init!(name: String) {
        guard name != "" else { return nil }
        self.name = name
    }
}
let abc = Human.init() // 에러 init?()은 Human? 타입

let abc = Human.init(name: "abc") // Human
let efg = Human.init(name: "") // nil
  • 이 생성자를 받는 인스턴스의 타입이 Non-Optional 타입일 경우, Non-Optional 타입으로 자동으로 묵시적 옵셔널 바인딩을 해서 리턴

failable initializers의 오버로딩/오버라이딩

  • initializers를 오버로딩 할 경우, failable / nonfailable을 구분하지 않는다
class Human{
	init() {}
    init?(name: String) { }
    init!(name: String { } // 에러
}
  • 슈퍼 클래스의 failable initializers를 자식 클래스에서 nonfailable initializers로 오버라이딩 해도 되지만, 이땐 당연히 failable initializer만 사용할 수 없다.
class Human{
    init?(name: String) { }
}

class Person: Human{
	override init(name: String) {
    	super.init(name: "") //에러 super.init(name:)은 실패할 수 있는 초기화
    }
}

deinit

소멸자라고 불리며, 클래스 전용으로 인스턴스가 메모리에서 정리되기 전에 자동으로 호출
deinit은 메서드 하나만 작성할 수 있게 제한되고, 직접 호출할 수는 없다.

class Human {
    deinit {
        print("☺️")
    }
}
 
var sodeul: Human? = Human.init()
sodeul = nil  // 메모리에서 해제됨과 동시에 deinit 실행되어 ☺️가 프린트됨
  • 메모리가 해제 되기 전에 해야할 작업을 지정해두면 메모리가 해제될 때 호출

참조
개발자 소들이

0개의 댓글