[TIL] Swift 문법 초기화(Initialization) - 1

2023. 5. 10. 02:20·Swift/문법
728x90

swift

초기화

  • 클래스, 구조체, 열거형 인스턴스를 사용하기 위해 준비 작업을 하는 단계
  • 각 저장 프로퍼티의 초기 값을 설정
  • 초기화 과정은 initializer를 정의 하는 것으로 구현
  • Swift initializer는 값을 반환 ❌
  • 초기화와 반대로 여러 값과 자원의 해지를 위해 deinitializer도 사용

저장 프로퍼티를 위한 초기값 설정(Setting initial Values for Stored Properties)

  • 인스턴스의 저장 프로퍼티는 사용하기 전에 반드시 특정 값으로 초기화
  • 기본값으로 설정할 수 있고, 특정 값을 설정할 수도 있음
  • initializer에서 저장 프로퍼티에 값을 직접 설정하면 프로퍼티 옵저버가 호출되지 않고 값 할당이 수행

이니셜라이저 (Initializers)

  • 이니셜라이저는 특정 타입의 인스턴스를 생성, 이니셜라이저의 가장 간단한 형태는 파라미터가 없고 init 키워드 사용
  • init () { }
struct Bulmang {
    var weight: Double
    init() {
        weight = 66.7
    }
}

var bulmang = Bulmang()
print("불망의 몸무게는 \\(bulmang.weight)")

기본 프로퍼티 (Default Property Values)

  • 프로퍼티의 선언과 동시에 값을 할당하면 그 값을 초기값으로 사용
  • 항상 같은 초기 값을 갖는다면 기본 프로퍼티를 사용하는 것이 좋음, 프로퍼티에 타입을 선언하지 않아도 컴파일러는 타입추론을 함
// 프로퍼티를 선언과 동시에 초기 값을 할당
struct Bulmang {
    var weight = 66.7
}

var bulmang = Bulmang()
print("불망의 몸무게는 \\(bulmang.weight)")

커스터마이징 초기화(Customizing Initialization)

  • 초기화 프로세스를 입력 값과 옵셔널 프로퍼티 타입 혹은 상수 값을 할당해서 커스터마이징

초기화 파라미터(Initialzation Parameters)

  • 초기화 정의에 파라미터를 정의해 사용할 수 있음
struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0

파라미터 이름과 인자 레이블 (Parameter Names and Argument Labels)

  • 메소드 파라미터와 초기화 파라미터 모두 파라미터 이름과 인자 레이블을 갖지만,이니셜라이저는 특정 메소드에서 지정하는 메소드 이름을 지정하지 않고 이니셜라이저 식별자로 파라미터를 사용
  • 모든 파라미터는 인자 레이블을 갖는데 만약 사용자가 이 레이블을 지정하지 않느면 Swift가 자동으로 하나를 할당
struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }
}
// 두 초기화 구문 모두 각 초기화 구문 파라미터에 값을 제공하여 새로운 Color 인스턴스를 생성
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)
// 인수 라벨을 사용하지 않고 초기화 구문을 호출할 수 없습니다. 인수 라벨은 정의 되었다면 항상 사용되어야 하고 생략 시 컴파일 시 에러가 발생
let veryGreen = Color(0.0, 1.0, 0.0)
// this reports a compile-time error - argument labels are required
// 초기화 구문 파라미터에 인수 라벨 사용을 원치 않을 경우 명시적으로 인수 라벨 대신에 언더바 (_)를 작성하여 기본 동작을 재정의
struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius is 37.0
// 초기화 구문 호출 Celsius(37.0) 은 인수 라벨이 필요치 않다는 의도가 명확합니다. 따라서 초기화 구문을 init(_ celsius: Double) 로 작성하여 이름없는 Double 값을 제공하여 호출

옵셔널 프로퍼티 타입(Optional Property Types)

  • 사용자 타입이 초기화 동안 값을 설정할 수 없거나 추후에 "값 없음"을 가질 수 있기 때문에 논리적으로 "값 없음"을 가질 수 있는 하나의 저장된 프로퍼티를 가지고 있다면 옵셔널 타입으로 프로퍼티를 선언
  • 자동적으로 초기화 동안 "아직 값 없음"을 가진다는 의도를 위해 nil 의 값으로 초기화
class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// Prints "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese."
// 응답은 질문 되기 전까지 알수없어서 response 프로퍼티는 String? 타입또는 옵셔널 String타입으로 선언
// 새로운 인스턴스 SurveyQuestion이 초기활 될 때 nil이 자동으로 할당

초기화 동안 프로퍼티 상수 할당(Assigning Constant During Initialization)

  • 초기화가 완료될 때까지 한정된 값으로 설정되는 한 초기화 중 언제든지 프로퍼티 상수에 값을 할당할 수 있음
  • 프로퍼티 상수에 값이 할당되면 더 이상 수정 불가.
// text 프로퍼티는 프로퍼티 변수보다 프로퍼티 상수로 사용하기 위해 위의 SurveyQuestion 예제를 수정가능
// text 프로퍼티는 현재 상수이지만 여전히 클래스의 초기화 구문 내에서 설정할 수 있음
class SurveyQuestion {
    let text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let beetsQuestion = SurveyQuestion(text: "How about beets?")
beetsQuestion.ask()
// Prints "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"

기본 초기화 구문(Default Initializers)

  • Swift는 모든 프로퍼티에 대한 기본값을 제공하고 적어도 하나의 초기화 구문을 제공하지 않는 모든 구조체 또는 클래스에 대해 기본 초기화 구문을 제공
  • 모든 프로퍼티가 기본값으로 설정된 새로운 인스턴스를 생성
// 쇼핑 리스트에 있는 항목의 이름, 수량, 그리고 구매 상태를 캡슐화하는 ShoppingListItem 이라는 클래스를 정의
class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()
// 쇼핑리스트아이템클래스의 모든 프로퍼티는 기본값을 가지고 있고 상위 클래스가 없는 기본클래스타입
// 자동적으로 모든 프로퍼티를 기본값으로 설정한 새로운 인스턴스를 생성하는 기본 초기화 구문 구현
// ShoppingListItem() 클래스에 기본 초기화 구문 사용, item이라는 변수에 인스턴스 할당

구조체 타입에 대한 멤버별 초기화 구문(Memberwise Initializers for Structure Types)

  • 구조체 타입은 자신의 초기화 구문을 정의하지 않으면 자동적으로 멤버별 초기화 구문을 받음
  • 구조체는 기본값을 가지지 않은 저장된 프로퍼티라도 멤버별 초기화 구문을 받음
  • 새로운 구조체 인스턴스에 멤버 프로퍼티를 초기화 하기 위한 짧은 구문 방법
  • 새로운 인스턴스의 프로퍼티를 위한 초기화 값은 이름으로 멤버별 초기화 구문으로 전달
// width, height라는 2개의 프로퍼티를 가지는 Size 구조체 정의
// 두 프로퍼티 모두 0.0 의 기본값이 할당되어 Double 타입으로 추론

struct Size {
    var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)

값 타입을 위한 초기화 구문 위임(Initializer Delegation for Value Types)

  • 초기화 구문은 인스턴스의 초기화 부분을 수행하기 위해 다른 초기화 구문을 호출
  • 여러 초기화 구문에서 코드가 중복되는 것을 방지
  • 구조체와 같은 값 타입에서 초기화 과정에 사용
  • 초기화 메소드 간에 코드 중복을 최소화 시켜 가독성과 유지보수성이 높아짐
  • init 키워드를 사용하여 초기화 메소드를 정의
  • 다른 초기화 메소드를 호출할 때 self.init 형태 사용
  • 값 타입에 대해 사용자 화 초기화 구문을 정의한다면 그 타입에 대해 기본 초기화 구문 또는 구조체의 경우 멤버별 초기화 구문에 더이상 접근할 수 없음
struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}

struct Rect {
    var origin = Point()
    var size = Size()
    init() {}
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}
// 구조체를 수신했을 때 기본 초기화 구문과 기능적으로 동일
let basicRect = Rect()
// basicRect's origin is (0.0, 0.0) and its size is (0.0, 0.0)

// origin과 size 인수값을 적절한 저장된 프로퍼티에 할당
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),size: Size(width: 5.0, height: 5.0))
// originRect's origin is (2.0, 2.0) and its size is (5.0, 5.0)

// center 점과 size 값을 기반으로 적절한 원점을 계산하는 것을 시작하고 다음 적절한 프로퍼티로 새로운 원점과 크기를 저장하는 init(origin:size:) 초기화 구문을 호출
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)

클래스 상속과 초기화 (Class Inheritance and Initialization)

  • 상위 클래스로 부터 상속한 클래스의 모든 프로퍼티를 포함하는 모든 클래스의 저장된 프로퍼티는 초기화중에 반드시 초기값이 할당해야 됨

지정된 초기화 구문과 편의 초기화 구문(Designated Initializers and Convenience Initializers)

  • 클래스에 주 초기화 구문, 지정된 초기화 구문은 해당 클래스에 의해 도입된 모든 프로퍼티를 완벽하게 초기화하고 적절한 상위 클래스 초기화를 호출하여 상위 클래스 체인까지 초기화 프로세스를 계속 진행
  • 모든 클래스에는 최소 하나의 지정된 초기화 구문이 있어야함
  • 경우에 따라 자동 초기화 구문 상속(Automatic Initializer Inheritance)에서 설명하듯이 상위 클래스에서 하나 이상의 지정된 초기화 구문을 상속하는 것으로 충족
  • 편의 초기화 구문(Convenience initializers)
    • 클래스에 대해 초기화 구문을 지원하는 보조 초기화 구문
    • 지정된 초기화 구문의 파라미터를 기본값으로 설정하여 편의 초기화 구문과 동일한 클래스에서 지정된 초기화 구문을 호출하도록 편의 초기화 구문을 정의
    • 특정 사용 케이스 또는 입력 값 타입에 대한 해당 클래스의 인스턴스를 생성하기 위해 편의 초기화 구문을 정의
    • 클래스에 필요하지 않은 경우 편의 초기화 구문(Convenience initializers)을 제공할 필요가 없음
    • 일반적인 초기화 패턴에 대한 바로가기가 시간을 절약하거나 클래스 초기화를 더 명확하게 만들 때마다 편리한 초기화 구문을 만듬
class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    convenience init(name: String) {
        self.init(name: name, age: 0)
    }
}

모르는 용어

Superclass Chain

  • OOP에서 상속관계를 형성하는 class간의 관계를 나타냄
  • 하위 class가 상위 class부터 상속받은 method, property, 초기화 메서드등 사용
  • 코드의 재사용성과 유지보수성이 높아지고 상위클래스체인(Superclass Chain)을 이해하면 오류수정하거나 디버깅할 때 도움이 됨
728x90

'Swift > 문법' 카테고리의 다른 글

[TIL] Swift 문법 옵셔널 체이닝(Optional Chaining)  (1) 2023.05.17
[TIL] Swift 문법 초기화(Initializer) - 2  (0) 2023.05.11
[TIL] Swift 문법 상속(Inheritance)  (0) 2023.05.05
[TIL] Swift 문법(Subscripts)  (0) 2023.05.03
[TIL] Swift 문법 메소드(Methods)  (0) 2023.04.28
'Swift/문법' 카테고리의 다른 글
  • [TIL] Swift 문법 옵셔널 체이닝(Optional Chaining)
  • [TIL] Swift 문법 초기화(Initializer) - 2
  • [TIL] Swift 문법 상속(Inheritance)
  • [TIL] Swift 문법(Subscripts)
bulmang
bulmang
모바일 개발자 도전
  • bulmang
    bulmang
    bulmang
  • 전체
    오늘
    어제
    • 분류 전체보기 (208)
      • 알고리즘 (68)
        • List (3)
        • Two Pointer (6)
        • Binary Search (4)
        • Prefix Sum (3)
        • Sort (4)
        • Brute Force (5)
        • Array (2)
        • String (4)
        • 프로그래머스 (12)
        • 백준 (9)
        • Queue (2)
        • Stack (2)
        • Recursion (12)
      • Computer Science (16)
        • Computer Architecture (6)
        • Operating System (5)
        • Network (2)
        • 기타 (2)
        • System Programming (1)
      • Swift (70)
        • 개발 (24)
        • 정리 (25)
        • 문법 (20)
      • Flutter (24)
      • 기타 (12)
        • 후기 (12)
      • Git (6)
      • Ios 오픈소스 (5)
      • UI 디자인 (5)
      • AppleScript (2)
  • 링크

    • Notion
    • Github
  • 태그

    IOS
    Java
    피플
    til
    문법
    협업
    riverpod
    알고리즘
    Xcode
    재귀
    백준
    SwiftUI
    FLUTTER
    코딩테스트
    Apple Developer Academy
    today i learned
    개발
    Swift
    자료구조
    컴퓨터구조
  • 최근 댓글

  • 최근 글

  • 인기 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.2
bulmang
[TIL] Swift 문법 초기화(Initialization) - 1
상단으로

티스토리툴바