ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • swift - Initializer and Deinitializer #4 (Initializer Delegate)
    swift 2021. 1. 12. 16:07

    Initializer Delegate

     

    값 형식과 참조 형식에서 서로 다른 규칙으로 구현된다.

     

    값 형식은 상속이 불가능하고 init 종류가 하나기 때문에 상대적으로 단순

     

    값 형식의 Initializer

    init이 실행이 완료되었을때 모든 속성이 초기화 되기만 하면 어떤 패턴으로 구현되어도 상관 없다.

     

    참조 형식의 Initializer

    상속을 지원하고 구현할 수 있는 init의 종류가 두가지이기 때문에 복잡

     

    특히 상속 계층을 따라 올라가면서 모든 init이 순서대로 호출되는 것이 매우 중요

     

     

    규칙

     

    1. designated init은 반드시 super class의 designated init을 호출해야한다.  -> Delegate up

             * 파란색이 Deisgnated init 회색은 convenience init

     

     2. convenience init은 반드시 동일한 클래스의 init을 호출해야 한다.

     

    3. convenience init을 호출햇을때 최종적으로 동일한 클래스의 designated init이 호출되어야 한다.

     

    struct Size {
       var width: Double
       var height: Double
    
       init(w: Double, h: Double) {
          width = w
          height = h
       }
    
       init(value: Double) {
        // init에서 다른 init을 호출하는 것을 delegate라고 한다.
        self.init(w: value, h: value)
       }
    }
    
    
    
    class Figure {
        let name: String
        
        init(name: String) {
            self.name = name
        }
        
        convenience init() {
            // 규칙 2. convenience init은 동일한 class의 init을 호출한다.
            // 규칙 3. convenience init을 호출할때는 최종적으로 designated init이 호출되어야 한다.
            self.init(name: "Unknown")
        }
    }
    
    class Rectangle: Figure {
        var width = 0.0
        var height = 0.0
        
        init(n: String, w: Double, h: Double) {
           // first phase
            width = w
            height = h
            
            // 규칙 1. delegate up (subClass의 init에서는 superClass의 init을 호출해야 함)
            super.init(name: n)
            
            // second phase
        }
        
        convenience init(value: Double) {
            self.init(n: "rect", w: value, h: value)
        }
    }
    
    class Square: Rectangle {
        
        convenience init(value: Double) {
            // convenience init에서는 어떠한 경우에도 delegate up이 불가능 -> super.init호출이 불가능
            self.init(n: "Square", w: value, h: value)
        }
        
        convenience init() {
            self.init(value: 0.0)
        }
    }

    Class Initializer는 두단계로 수행된다.

     

    1. First phase

    선언되어 있는 모든 속성이 초기화

     

    초기화는 subclass -> superclass 상속계층을 따라 아래서 위로

     

    모든 속성이 초기화되면 첫번째 단계가 완료되고 인스턴스의 유효성이 확보됨

     

     

    2. Second phase

     

    바로 이어서 두번째 단계가 시작되는데

     

    super class -> Subclass 

     

    첫번째에서 할 수 없었던 작업을 수행한다.

     

    인스턴스 속성에 접근하거나 메소드를 호출하는 것도 가능

     

    부가적인 단계기 때문에 자동적으로 수행되는 예도 많음

     


     

    Square 클래스의 파라미터가 없는 init 실행하면 밑에와 같은 순서로 initialization이 진행된다.

    first phase 완료

     

    second phase 완료

    댓글

Designed by Tistory.