일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 플로우 차트
- PushNotification
- 플로우차트
- git사용법
- 계산기
- github란
- 애플
- 스위프트
- UIViewController
- JSONSerialization
- 정규표현식
- xcode
- 깃허브
- 정규식
- OS
- flow chart
- github
- flowchart
- 흐름도
- Git과 Github차이점
- 순서도
- Regex
- ios
- GitvsGithub
- git
- APNS
- git이란
- 깃
- 백준
- swift
- Today
- Total
Diana의 iOS 개발일기
[스위프트 프로그래밍 3판] - 11. 인스턴스 생성 및 소멸 본문
인스턴스는 메모리와 직접적으로 연관이 있다보니 수 많은 언어들에서 중요하게 다뤄집니다.
스위프트 또한 메서드, 프로퍼티 등을 사용하기 위해서는 인스턴스 생성이 거의 필수로 이루어지고 메모리의 낭비를 막기 위해서는 생성된 인스턴스를 알맞게 소멸시켜줄 수 있어야 합니다.
이번 내용은 이니셜라이저를 통한 인스턴스 생성, 초기화 등을 통한 인스턴스을 다루고 있습니다.
[이니셜라이저(Initializer)]
1. 초기화(initialize)
구조체, 클래스 그리고 열거형 등은 생성한 뒤 인스턴스를 사용하기 위해서는 프로퍼티 값들을 초기화 해주어야 합니다.
초기화 방법에는 두가지가 있는데 하나는 저장 프로퍼티 생성과 동시에 초기화를 해주는 방법이고 다른 하나는 아래와 같이 init 키워드를 사용하여 이니셜라이저를 생성 한 뒤 그 안에서 초기화를 해주는 방법이 있습니다.
참고로 구조체는 생성 시 자동으로 모든 프로퍼티를 포함한 이니셜라이저인 멤버와이즈 이니셜라이저가 생성됩니다.
이는 클래스에서는 지원하지 않으므로 구분하여 알아둘 필요가 있습니다.
//클래스
class SomeClass {
init(){//클래스의 경우 생성 후 이니셜라이저를 통해 초기값을 지정해주어야 인스턴스 사용이 가능하다
//초기화를 위한 코드(이니셜라이저)
}
}
//구조체
struct SomeStruct {
init(){//구조체는 생성시 이니셜라이저가 자동으로 생성된다
//초기화를 위한 코드
}
}
//열거형
enum SomeEnum {
case someCase
init(){
//열거형은 초기화할 때 반드시 case중 하나가 되어야 한다
}
}
2. 매개변수(Parameter)
이니셜라이저 또한 메서드의 한 종류로 볼 수 있으므로 매개변수를 가진 사용자 정의 이니셜라이저를 생성할 수 있습니다.
struct Area{
var squareMeter: Double
init(fromPy py: Double) { //사용자 정의 이니셜라이저는 한개 이상 설정 가능합니다
squareMeter = py * 3.3058
}
init(fromSquareMeter squareMeter:Double) {
self.squareMeter = squareMeter
}
init(value: Double) {
squareMeter = value
}
init(_ value: Double) {
squareMeter = value
}
}
let roomOne: Area = Area(fromePy: 15.0)
print(roomOne.squareMeter) //49.587
let roomTwo: Area = Area(fromSquareMeter: 33.06)
print(roomTwo.squareMeter) //33.06
let roomThree: Area = Area(value: 30.0)
let roomFour: Area = Area(55.0)
사용자 정의 이니셜라이저를 생성할 경우 기본 이니셜라이저(init())는 별도로 구현해야 사용할 수 있으며 이니셜 라이저 안에 또다른 이니셜라이저를 사용함으로써 초기화를 위임할 수 도 있습니다.
enum Student {
case elementary, middle, high
case none
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
참고로 초기화는 옵셔널 프로퍼티가 아닌 이상 무조건 이루어져야 한다 는 조건을 가지고 있으며 반대로 옵셔널 프로퍼티의 경우 초기화를 하지 않아도 사용이 가능합니다.
한 구조체나 클래스 안에 옵셔널이 지정된 프로퍼티와 그렇지 않은 프로퍼티가 동시에 존재한다면 옵셔널이 지정되지 않은 프로퍼티만 초기화 하는 것도 가능합니다.
class Person {
var name: String
var age: Int?
init(name: String){//옵셔널로 지정되지 않은 name만 초기화 합니다
self.name = name
}
}
let myName: Person = Person(name: "test")
print(myName.age) //초기화 되지 않은 옵셔널 프로퍼티를 출력하므로 결과는 nil 입니다
3. 실패 가능한 이니셜라이저(Failable initializer)
이니셜라이저를 사용할 때 생기는 여러 예외 상황 중 하나는 이니셜라이저의 전달인자로 잘못된 값이 들어가는 것 입니다. 이 경우 인스턴스는 초기화에 실패하여 에러를 띄우게 됩니다.
이러한 예외상황들을 고려하여 init키워드 뒤에 "?"를 붙여 실패 가능성을 열어두는 것을 실패 가능한 이니셜라이저 라고 합니다.
결국 nil을 염두해 놓은, 옵셔널이 떠오르는 기능임을 알 수 있습니다.
enum Student: String {
case elementary = "초등학생", middle = "중학생", high = "고등학생"
init?(koreanAge: Int) { //실패 가능한 이니셜라이저
switch koreanAge{
case 8...13:
self = .elementary
case 14...16:
self = .middle
case 17...19:
self = .high
default:
return nil
}
}
init?(bornAt: Int, currentYear: Int) {
self.init(koreanAge: currentYear - bornAt + 1)
}
}
var younger: Student? = Student(koreanAge: 20) //20이상은 case에 없네요
print(younger) //전달인자가 잘못되었어! nil을 반환합니다
younger = Student(bornAt: 2020, currentYear: 2016) //2020년에 태어나 현재 2016년이다? 이상하네요
print(younger) //nil
younger = Student(rawValue: "대학생")
print(younger) //nil
younger = Student(rawValue: "고등학생")
print(younger)
[디이니셜라이저(Deinitializer)]
클래스 인스턴스에서는 이니셜라이저를 통해 메모리를 할당해서 사용을 한 뒤에는 할당되었던 메모리를 해제해 주어야 메모리 낭비를 막을 수 있습니다.
이 역할을 해주는 것이 바로 디이니셜라이저로, 디이니셜라이저는 클래스 인스턴스에서만 사용되지만 모든 클래스 인스턴스가 아닌 외부 자원을 인스턴스 내부에 가져와 사용한 인스턴스에 한에 유용하게 사용됩니다.
class SomeClass {
deinit {//해당 클래스 인스턴스는 메모리 해제 전 아래 구문을 출력한다
print("Instance will be deallocated immediately")
}
}
var instance: SomeClass? = SomeClass()
instance = nil
해당 글은 야곰님의 스위프트 프로그래밍 3판 을 기반으로 한 정리 글이며 문제가 있을 시 삭제하도록 하겠습니다.
스위프트 프로그래밍 3판 eBook 구매 링크: www.yes24.com/Product/Goods/81530016
야곰님의 블로그: blog.yagom.net/
'Swift > 책 정리' 카테고리의 다른 글
[스위프트 프로그래밍 3판] - 14. 옵셔널 체이닝과 빠른 종료 (1) | 2021.03.17 |
---|---|
[스위프트 프로그래밍 3판] - 13. 클로저 (0) | 2021.03.11 |
[스위프트 프로그래밍 3판] - 12. 접근제어 (0) | 2021.03.10 |
[스위프트 프로그래밍 3판] - 10. 프로퍼티와 메서드 (0) | 2021.03.08 |
[스위프트 프로그래밍 3판] - 9. 구조체와 클래스 (0) | 2021.03.08 |