Swift/Swift 기본문법

Swift 기본 문법 - 13. 인스턴스의 생성과 소멸

728x90

13. 인스턴스의 생성과 소멸 

 

13.1 인스턴스 생성

 

이니셜라이저(initializer)를 정의하면 초기화 과정을 직접 구현할 수 있습니다.

이니셜라이저의 역할은 그저 인스턴스의 첫 사용을 위해 초기화하는 것 뿐입니다.

init 메서드는 클래스, 구조체, 열거형 등의 구현부 또는 해당 타입의 익스텐션 구현부에 위치합니다.

 

class SomeClass {
    init() {
        // 초기화할 때 필요한 코드
    }
}

struct SomeStruct {
    init() {
        // 초기화 할 때 필요한 코드
    }
}

enum SomeEnum {
    case someCase
    
    init() {
        // 열거형은 초기화할 때 반드시 case중 하나가 되어야 합니다.
        self = .someCase
    }
}

// 저장 프로퍼티 초기화
struct Area {
    var squareMeter: Double
    
    init() {
        squareMeter = 0.0 // squareMeter의 초깃값 할당
    }
}

let room: Area = Area()
print(room.squareMeter) // 0.0

//이니셜라이저 매개변수

struct AreaParam {
    var squareMeter: Double
    
    init(fromPy py: Double) {                   // 첫. 번째 이니셜라이저
        self.squareMeter = py * 3.3058
    }
    
    init(fromSquareMeter squareMeter: Double) { // 두 번째 이니셜라이저
        self.squareMeter = squareMeter
    }
    
    init(value: Double) {                       // 세 번째 이니셜라이저
        squareMeter = value
    }
    
    init(_ value: Double) {                     // 네 번째 이니셜라이저
        squareMeter = value
    }
}

let roomOne: AreaParam = AreaParam(fromPy: 15.0)
print(roomOne.squareMeter)  // 49.589

let roomTwo: AreaParam = AreaParam(fromSquareMeter: 33.06)
print(roomTwo.squareMeter) // 33.06

let roomThree: AreaParam = AreaParam(value: 30.0)
let roomFour: AreaParam = AreaParam(55.0)

Area() // 오류발생

 

13.1.4 상수 프로퍼티

상수로 선언된 저장 프로퍼티는 인스턴스를 초기화하는 과정에서만 값을 할당할 수 있으며, 처음 할당된 이후로는 값을 변경 할 수 없습니다.

 

 

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

기본 이니셜라이저는 저장프로퍼티 기본값이 모두 지정되어 있고, 동시에 사용자 정의 이니셜라이저가 정의되어 있지 않은 상태에서 제공됩니다.

구조체는 이니셜라이저를 구현하지 않으면 프로퍼티의 이름으로 매개변수를 갖는 이니셜라이저인 멤버와이즈 이니셜라이저를 기본으로 제공합니다.

클래스에서는 이걸 제공을 하지 않아서 안되었던 거구나.

struct Point {
    var x: Double = 0.0
    var y: Double = 0.0
}

struct Size {
    var width: Double = 0.0
    var height: Double = 0.0
}

// 멤버와이즈 이니셜라이저
let point: Point = Point(x: 0, y: 0)
let size: Size = Size(width: 50.0, height: 50.0)

// 구조체의 저장프로퍼티에 기본 값이 있는 경우 필요한 부분만 초기화 가능합니다.

let someSize: Size = Size(width: 50)

 

13.1.6 초기화 위임

구조체와 열거형은 코드의 중복을 피하기 위해 이니셜라이저가 다른 이니셜라이저에게 일부 초기화를 위임하는 초기화 위임을 구현 할 수 있습니다.

하지만 클래스는 상속을 지원하는 터라 간단한 초기화 위임도 할 수 없습니다.

 

self.init을 사용하여 다른 이니셜라이저를 호출 할 수 있습니다.

 

enum Student {
    case elementary, middle, high
    case none
    
    // 사용자 정의 이니셜라이저가 있는 경우 init() 메서드를 구현해 주어야 기본 이니셜라이저를 사용할수있습니다.
    init() {
        self = .none
    }
    
    init(koreanAge: Int) {
        switch koreanAge {
        case 8...13:
            self = .elementary
        case 14...16:
            self = .middle
        case 17...19:
            self = .high
        default:
            self = .none
        }
    }
    
    init(bornAt: Int, currentYear: Int) {
        self.init(koreanAge: currentYear - bornAt + 1)
    }
}

var younger: Student = Student(koreanAge:  16)
print(younger) // middle

younger = Student(bornAt: 1998, currentYear: 2016)
print(younger)  // high

 

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

이니셜라이저의 전달인자로 잘못된 값이나 적절치 못한 값이 전달되었을 때, 이니셜라이저는 초기화에 실패할 수 있습니다.

실패 가능성을 내포한 이니셜라이저를 실패 가능한 이니셜라이저 라고 부릅니다.

 

init? 을 통해 설정 할 수 있습니다.

class Person {
    let name: String
    var age: Int?
    
    init?(name: String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
    init?(name: String, age: Int) {
        if name.isEmpty || age < 0 {
            return nil
        }
        self.name = name
        self.age = age
    }
}

 

13.1.8 함수를 사용한 프로퍼티 기본값 설정

 

함수와 클러저를 통해 프로퍼티 값을 설정 할 수 있습니다.

다만 클로저를 사용한다면 클로저가 실행되는 시점은 다른 프로퍼티 값이 설정되기 전이기 때문에 내부에서 인스턴스의 다른 프로퍼티를 self를 통해 접근 할 수 없습니다.

메모리에 올라가 있지 않으니 당연할 것 같습니다.

 

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

class SchoolClass {
    var name: String = "hi"
    // 새로운 인스턴스를 생성하고 사용자 정의 연산을 통한 후 반환해줍니다.
    // 반환되는 값의 타입은 [Student]여야합니다.
    var student: [Student] = {
        
        //print(self.name) // 에러
        var arr: [Student] = [Student]()
        
        for num in 1...15 {
            var student: Student = Student(name: nil, number: num)
            arr.append(student)
        }
        
        
        return arr
    }()
}

let myClass: SchoolClass = SchoolClass()
print(myClass.student.count) // 15

 

반응형