[Swift๐ฆฉ] #14 ์ด๊ธฐํ
- ์ด๊ธฐํ (Initialization) : ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ค๋นํ๋ ๋จ๊ณ. (์ด๊ธฐ๊ฐ์ ์ค์ ํด์ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋นํ๊ณ ...)
- initializer ๋ฅผ ์ ์ํ์ฌ ๊ตฌํํ ์ ์๋ค.
- ๊ฐ์ ๋ฐํํ์ง ์์.
- ์ด๊ธฐํ์ ๋ฐ๋๋ก, ๊ฐ๊ณผ ์์์ ํด์ง๋ฅผ ์ํด deinitializer ๋ ์ฌ์ฉํ ์ ์๋ค.
1. ์ ์ฅ ํ๋กํผํฐ์ ์ด๊ธฐ๊ฐ ์ค์
-> ์ฌ์ค ์ ์๋ ๋ด์ฉ๋ค์, ์ ์ฅ ํ๋กํผํฐ๋ฅผ ์ด๊ธฐํํ๋ ์์๋... ํ์ ์ ๋ฐ๋ผ ์ด๊ธฐํ ๋ฐฉ๋ฒ / ํ๋ก์ธ์ค์ ์ฐจ์ด๋ฅผ ๋ํ๋ด๋ ๊ฒ์ด๊ณ ํต์ฌ์ ์ฌ๊ธฐ.
- ์ธ์คํด์ค์ ์ ์ฅ ํ๋กํผํฐ๋ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ฐ๋์ ํน์ ๊ฐ์ผ๋ก ์ด๊ธฐํ ๋์ด์ผ ํ๋ค.
- initializer ์์ ํ๋กํผํฐ์ ๊ฐ์ ์ค์ ํ๋ฉด, ํ๋กํผํฐ ์ต์ ๋ฒ๊ฐ ํธ์ถ๋์ง ์๋๋ค.
๊ฐ๋ฐํ ๋ ์๊ฐ ํ์
initializer
init() {
// ๊ฐ์ฅ ๊ฐ๋จํ ํํ. ํ๋ผ๋ฏธํฐ X, init ํค์๋ ์ฌ์ฉ.
}
struct Fahrenheit {
var temperature: Double
init() {
temperature = 32.0
}
}
var f = Fahrenheit()
print("๊ธฐ๋ณธ ์จ๋๋ \(f.temperature)ยฐF ์
๋๋ค.")
// Prints "๊ธฐ๋ณธ ์จ๋๋ 32.0ยฐF ์
๋๋ค."
Default Property Values
์์ ์์์ฒ๋ผ ํญ์ ๊ฐ์ ๊ฐ์ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ๊ฐ์ง๋ ๊ฒฝ์ฐ,
์ ์ธ๊ณผ ๋์์ ๊ฐ์ ํ ๋นํ๋ ๋ฐฉ์์ผ๋ก ์ด๊ธฐ๊ฐ์ ์ค์ ํ ์ ์๋ค.
struct Fahrenheit {
var temperature = 32.0
}
2. Customizing Initializer โญ๏ธโญ๏ธ
- ์ด๊ธฐ๊ฐ์ ํจ์์ฒ๋ผ ์ ๋ ฅ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์์ ์ปค์คํฐ๋ง์ด์ง ํ ์ ์๋ค.
- ์ธ๋ถ ์ด๋ฆ, ๋ด๋ถ ์ด๋ฆ ์ฌ์ฉ ๊ฐ๋ฅ.
์ด๊ธฐํ ํ๋ผ๋ฏธํฐ
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 boilingPointOfWater = Celsius(fromFahrenheit: 212.0) // 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15) // 0.0
ํ๋ผ๋ฏธํฐ ์ด๋ฆ๊ณผ ์ธ์ ๋ ์ด๋ธ ~= ์ค๋ฒ๋ก๋ฉ
- ํจ์์ฒ๋ผ ๋ฉ์๋ ์ด๋ฆ์ ์ฌ์ฉํ์ง ์๊ณ init ์ผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์,
- ์ฌ๋ฌ init ์ ๊ตฌ๋ณํ๋๋ฐ ์์ด์ ์ธ์ ์ด๋ฆ๊ณผ ๊ฐ์๊ฐ ์ค์ํ ์ญํ ์ ํ๋ค. (ํจ์์ ์ค๋ฒ๋ก๋ฉ์ฒ๋ผ)
- ์ด๊ธฐํ ์ ์ธ์ ์ด๋ฆ์ ์๋ฃ๊ณ ์ถ๋ค๋ฉด? ํจ์์ฒ๋ผ
_
์ฌ์ฉํ์!
struct Color {
let red, green, blue: Double
// ์ธ์ 3๊ฐ์ธ init
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
// ์ธ์ 1๊ฐ์ธ init
init(white: Double) {
red = white
green = white
blue = white
}
// ์ธ์ 1๊ฐ์ธ init ์ด๋ ์์ ๋ค๋ฆ.
// ์ธ์ ์ด๋ฆ์ด ๋ค๋ฅด๋๊น!!
init(red: Double) {
self.red = red
green = 0
blue = 0
}
}
Optinal Property Types
- ๋ง์ฝ ์ด๊ธฐํ๊ฐ ๋๋ฌ์ ๋, ๊ฐ์ด ๋น์ด์์ ์ ์๋ ์ํฉ์ด๋ผ๋ฉด optional ๋ก ์ ์ธํ์. ์๋์ผ๋ก nil ์ด ํ ๋น๋๋ค.
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.)"
- let ์ผ๋ก ์ ์ธ๋๋ฉด, ์ด๊ธฐํ ๊ณผ์ ์์๋ ๊ฐ์ ํ ๋นํ ์ ์์ง๋ง, ์ด๊ธฐํ ๋ ํ์๋ ์์ ํ ์ ์๋ค.
- ํด๋์ค ์ธ์คํด์ค์ ์๋ var ์ ๊ฒฝ์ฐ ์ธ์ ๋ ์ง ์์ ํ ์ ์์ง๋ง, ํ์ ํด๋์ค์์๋ ์์ ํ ์ ์๋ค.
3. Default Inititalizer
- init ์ ์ ์ํ์ง ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ ์ ๊ณตํด ์ค๋ค.
- ๋จ, ๋ชจ๋ ํ๋กํผํฐ์ ๊ธฐ๋ณธ๊ฐ์ด ์ค์ ๋ ๊ฒฝ์ฐ์๋ง ์ ๊ณต!
- ํ๋ผ๋ฏธํฐ๊ฐ ์๋ ํํ๊ฐ ์ ๊ณต๋จ.
class Album {
let titleSong: String = "INVU"
var hotSong: String? // ๊ธฐ๋ณธ์ ์ผ๋ก nil ์ด ์ ๊ณต๋จ.
var top100: Bool = true
}
var third = Album()
third.hotSong = "๊ทธ๋ฐ ๋ฐค"
๊ตฌ์กฐ์ฒด ํ์ ์ ๋ํ ๋ฉค๋ฒ๋ณ ์ด๊ธฐํ ๊ตฌ๋ฌธ
- ๊ตฌ์กฐ์ฒด ํ์ ์ init์ ์ ์ํ์ง ์์ผ๋ฉด, ์๋์ ์ผ๋ก ์ ์ฒด ๋ฉค๋ฒ์ ๋ํ init ์ด ์ฃผ์ด์ง๋ค.
- ๊ธฐ๋ณธ ๊ฐ์ด ์ ํด์ ธ ์๋ ๊ฒฝ์ฐ ์๋ต์ด ๊ฐ๋ฅํ๋ค.
struct Size {
var width = 0.0, height = 0.0
}
// ์๋ 3 ๋ผ์ธ์ ๋ชจ๋ ๊ฐ์ ๋ป.
let twoByTwo = Size(width: 2.0, height: 2.0)
let twoByTwo = Size(width: 2.0)
let twoByTwo = Size()
4. ๊ฐ ํ์ ์์ ์ด๊ธฐํ ์์(init delegation)
- ๊ฐ์ ๊ฐ ํ์
๋ด์ ์ด๊ธฐํ ๊ตฌ๋ฌธ์
self.init
์ผ๋ก ๋ค๋ฅธ ์ด๊ธฐํ ๊ตฌ๋ฌธ์์ ๋ถ๋ฅผ ์ ์๋ค. - ๊ฐ ํ์ ์์ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ํ๋ ์ ์ํ๋ฉด, ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ๊ธฐ๋ณธ ์ด๊ธฐํ ๊ตฌ๋ฌธ / ๋ฉค๋ฒ๋ณ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์ ๊ทผํ ์ ์๋ค.
- ๋ง์ฝ ๊ธฐ๋ณธ, ๋ฉค๋ฒ๋ณ, ์ปค์คํ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์ ๋ถ ์ ๊ทผํ๊ณ ์ถ๋ค๋ฉด, ์ปค์คํ init ์ extension ์ ์์ฑํ๋ฉด ๋๋ค.
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)
// ํ๋์ init ์์ ๋ค๋ฅธ init ํธ์ถ ๊ฐ๋ฅ.
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
5. ํด๋์ค ์์๊ณผ ์ด๊ธฐํ
- ๋ชจ๋ ์ ์ฅ ํ๋กํผํฐ(์์๋๊ฑฐ ํฌํจ)๋ ์ด๊ธฐํ ์ค์ ๋ฐ๋์ ์ด๊ธฐ๊ฐ์ด ํ ๋น ๋์ด์ผ ํ๋ค.
- ์ด๊ธฐํ๋ฅผ ์ํด์, designated init, convenience init ์ ์ ์ํ ์ ์๋ค.
1. Designated init
- ํด๋์ค์ ์ฃผ ์ด๊ธฐํ ๊ตฌ๋ฌธ
- ํด๋น ํด๋์ค์ ์๋ ๋ชจ๋ ํ๋กํผํฐ๋ฅผ ์ด๊ธฐํ
- ์์ ํด๋์ค ์ด๊ธฐํ๋ฅผ ํธ์ถํ์ฌ ์์ ํด๋์ค ์ฒด์ธ์ ์ญ~ ํ๊ณ ์ด๊ธฐํ ์งํ
- ์ด๊ธฐํ ํ๋ก์ธ์ค์ ์ต์์ ํด๋์ค(๋์ด์ ์ฌ๋ผ๊ฐ ๊ณณ์ด ์๋) ๋ฅผ funel ์ง์ ์ด๋ผ๊ณ ํ๋ค.
-> ํด๋์ค์ ๊ฑฐ์ ์กด์ฌํ์ง ์๊ณ (๊ธฐ๋ณธ init ์ด์ฉ), ์์ผ๋ฉด ํ๋๋ง ์๋ค.
// ์ ์ฅ ํ๋กํผํฐ์ ๋ํ ์ด๊ธฐํ๋ฅผ ๋ชจ๋ ํด๋๊ณ ,
class ViewModel {
var title: String = "title"
var content: String = "content"
var author: String?
}
// ๊ธฐ๋ณธ init ์ฌ์ฉ
let vm = ViewModel()
- ํด๋์ค๋ ์ ์ด๋ ํ๋์ designated init ์ ๊ฐ์ ธ์ผ ํ๋ค.
- ์์ ํด๋์ค์์ designated init ์ ์์ํ๋ ๊ฒ๋ ๊ฐ๋ฅ.
init(parameters) {
//statements
}
2. Convenience init
- ๋ณด์กฐ ์ด๊ธฐํ ๊ตฌ๋ฌธ
- designated init ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํ์ฌ, ๋์ผํ ํด๋์ค์ designated init ๋ฅผ ํธ์ถํ๋๋ก ์ ์ํ๋ค.
- ํน์ ์ผ์ด์ค๋ ์ ๋ ฅ ๊ฐ ํ์ ์ ๋ํ ํด๋์ค ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉํ๊ธฐ๋ ํ๋ค.
-> ๋์ฒด๋ก ์ ๊ณตํ์ง ์๊ณ , ์๊ฐ์ด ์ ์ฝ๋๊ฑฐ๋ ๋ ๋ช ํํ ์๋ฏธ๋ฅผ ์ง๋๋๋ง ๋ง๋ ๋ค.
convenience init(author: String) {
self.init() // ๊ฐ์ ๊ณ์ธต ๋ด์ desinated init ์ ๋ถ๋ฅธ๋ค.
self.author = author
}
let vm = ViewModel(author: "์ต๋ช
์ ์ฝ๋ผ๋ฆฌ")
convenience init(parameters) {
// statements
}
3. Initializer Delegation for Class Types โญ๏ธ
- designated init ์ ์์ ํด๋์ค์ designated init ์ ํญ์ ๋ถ๋ฌ์ผ ํจ. (Base Class ๋ผ๋ฉด ์์ธ)
- convenience init ์ ๊ฐ์ ํด๋์ค ๋ด์ ๋ค๋ฅธ init ์ ํญ์ ๋ถ๋ฌ์ผ ํจ.
- convenience init ์ ๊ถ๊ทน์ ์ผ๋ก ๊ฐ์ ํด๋์ค ๋ด์ ๋ค๋ฅธ designated init ์ ํญ์ ๋ถ๋ฌ์ผ ํจ.
๊ฒฐ๋ก : desinated init ์ ์์ ํด๋์ค๋ก, convenience ๋ ๊ฐ์ ํด๋์ค๋ก init ์ ์์ํ๋ค.
4. 2๋จ๊ณ ์ด๊ธฐํ โญ๏ธ
- ์ด๊ธฐํ๋ฅผ ์์ ํ๊ฒ ์ํํ๊ณ , ํด๋์ค์ ์ ์ฐ์ฑ์ ์ ๊ณตํ๊ธฐ ์ํด ์ํํ๋ค.
- ํ๋กํผํฐ ๊ฐ์ด ์ด๊ธฐํ ๋๊ธฐ ์ ์ ํ๋กํผํฐ์ ์ ๊ทผํ๋ ๊ฒ์ ๋ง๊ณ ,
- ๋ค๋ฅธ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ด ์์์น ๋ชปํ ๋ค๋ฅธ ๊ฐ์ ์ค์ ํ๋ ๊ฒ์ ๋ง๋๋ค.
๋จ๊ณ
- ๊ฐ stored property ๊ฐ ํด๋น ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ ํด๋์ค์ ์ํด ์ด๊ธฐ๊ฐ ํ ๋น
- (๋ชจ๋ ์ ์ฅ ํ๋กํผํฐ์ ๊ฐ์ด ๊ฒฐ์ ๋๋ฉด) ๊ฐ ํด๋์ค์ ์ ์ฅ๋ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐ๋ก ์ปค์คํ ํ ์ ์์.
NOTE
- Obj-c ์ ๊ฒฝ์ฐ๋ ๋ชจ๋ ํ๋กํผํฐ์ 0 or null ์ ๋ฃ๊ณ / ์ปค์คํ ํ๋ ๊ฒ์ ๋ฐํด
- Swift ๋ ๋ชจ๋ ํ๋กํผํฐ์ ์ฌ์ฉ์ ์ ์ ์ด๊ธฐ๊ฐ์ ์ค์ ํ ์ ์์ด์, 0 or nil ์ ๊ฐ์ง์ง ์๋ ํ์ ์ ๋์ฒํ ์ ์๋ค.
์์ ์ ๊ฒ
- designated init ์ ์์ ํด๋์ค์ init ์ ์์ํ๊ธฐ ์ ์, ํด๋์ค์ ์ถ๊ฐ๋ ๋ชจ๋ ํ๋กํผํฐ๊ฐ ์ด๊ธฐํ ๋์๋์ง ํ์ธ.
- designated init ์ ์์๋ ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๊ธฐ ์ ์, ์์ ํด๋์ค ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์์. ์๊ทธ๋ฌ๋ฉด ๋ถ๋ชจ์ ๊ฐ์ ๋ฎ์ด์ฐ์
- convenience init ์ ๋ชจ๋ ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๊ธฐ ์ ์ ๋ค๋ฅธ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์์. ์๊ทธ๋ผ designated ์ ๋ฎ์ด์ฐ์ฌ์ง.
- ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์ฒซ๋ฒ์งธ ์ด๊ธฐํ๊ฐ ์๋ฃ๋๊ธฐ ์ ๊น์ง ์ธ์คํด์ค ๋ฉ์๋ ํธ์ถ, ํ๋กํผํฐ ๊ฐ ์ฝ๊ฑฐ๋, self ๊ฐ์ ์ฐธ์กฐํ ์ ์๋ค.
init() {
// ์์๋์ง ์์ ๋ชจ๋ ํ๋กํผํฐ ์ด๊ธฐํ
super.init() // ์์๋ ๊ฐ ์ค์ ๋จ
// ์์๋ฐ์ ๋ชจ๋ ํ๋กํผํฐ ์ด๊ธฐํ
}
convenience init() {
self.init() // designated init
// ์ด๊ธฐํ ํ๊ณ ์ถ์ ๊ฐ ์ด๊ธฐํ.
}
1 ๋จ๊ณ
- class ์์ designated / convenience init ํธ์ถ
- class ์ ์๋ก์ด ์ธ์คํด์ค์ ๋ํ ๋ฉ๋ชจ๋ฆฌ ํ ๋น. (์์ง ์ด๊ธฐํ๋ X)
- designated init ์ด ๋ชจ๋ stored property ๊ฐ ๊ฐ์ ๊ฐ์ง๊ณ ์๋์ง ํ์ธ -> stored property ์ ๋ํ ๋ฉ๋ชจ๋ฆฌ ์ด๊ธฐํ
- designated init ์ ์์ ํด๋์ค ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์ด๊ธฐํ ์์.
- ๊ณ์ ์์ํด์ ์ต์์ ์ฒด์ธ๊น์ง ์ฌ๋ผ๊ฐ.
- ์ต์์ ์ฒด์ธ์์ ๋ชจ๋ stored property ๊ฐ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค๊ณ ํ์ธํ๋ฉด, ์ธ์คํด์ค์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ฒฝํ๊ฒ ์ด๊ธฐํ ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ.
2 ๋จ๊ณ
- ์ฒด์ธ์ ์ต์์์์ ํ๋์ฉ ์๋๋ก ๋ด๋ ค๊ฐ๋ฉด, designated init ์์ ์ถ๊ฐ๋ก ์ฌ์ฉ์๊ฐ ์ํ๋ ๋๋ก ์ธ์คํด์ค์ ๊ฐ์ ์ง์ ํ ์ ์๋ค. self ๋ก ์ ๊ทผํ์ฌ ํ๋กํผํฐ๋ฅผ ์์ ํ ์ ์๊ณ , ์ธ์คํด์ค ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์.
- ์ฒด์ธ์ ๋ชจ๋ convenience init ์ ์ฌ์ฉ์๊ฐ ์ํ๋ ๋๋ก ์ธ์คํด์ค์ ๊ฐ์ ์ง์ ํ๊ณ , self ๋ก ์์ ํ ์ ์๊ฒ ๋จ.
์ฌ๊ธฐ๋ถํฐ ๋ด์ผ!!
Override init
- Swift ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ํด๋์ค์ init ์ ์์ ํ๊ณ ์ ์ ํ ๊ฒฝ์ฐ์๋ง ์์ํ๊ธฐ ๋๋ฌธ์, (๋ถ๋ชจ ํด๋์ค์ ๊ฐ๋จํ init ์ด ํ์ ํด๋์ค์ ๋ชจ๋ ์ธ์๋ฅผ ํฌํจํ์ง ์์ ์ ์์ผ๋๊น.)
override init
์ผ๋ก ์ง์ ์์ ํด๋์ค์ designated init ์ ์ค๋ฒ๋ผ์ด๋ฉํ ์ ์๋ค.- ์์ ํด๋์ค์ convenience init ์ ํ์ ํด๋์ค์์ ํธ์ถ๋ ์ ์์. ๊ฐ์ ๊ฒ์ ํ์ํด๋์ค์์ ๊ตฌํํ๋๋ผ๋
override
๋ฅผ ์ธ ํ์๊ฐ ์๋ค. - ์์ ํด๋์ค์ ์๋์ผ๋ก ์ ๊ณต๋๋ init ์ ์ฌ์ฉํ ๋๋ override ๋ฅผ ์ฌ์ฉํด์ผ ํจ.
- ๋ฉ์๋, ์๋ธ์คํฌ๋ฆฝํธ์ ๋์ผํ๊ฒ ์์ ํด๋์ค์ ๊ฒ์ ํ์ธ.
class Vehicle {
var numberOfWheels = 0 // stored property ์ ๋ํ ๊ธฐ๋ณธ init ์ ๊ณต
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
class Bicycle: Vehicle {
// Vehicle ์ ๊ธฐ๋ณธ init ๊ณผ ๊ฐ๊ธฐ ๋๋ฌธ์,
// override ๋ฅผ ๋ถ์ฌ์ผ ํ๋ค.
override init() {
super.init() // ๋ถ๋ชจ๊บผ ๋จผ์ ์ธํ
ํ๊ณ ,
numberOfWheels = 2 // ์์๊ป ์ธํ
ํด์ผ ๋ฎ์ด์ฐ์ด์ง ์๋๋ค.
}
}
class Hoverboard: Vehicle {
var color: String
// ์ด๊ธฐํ ๊ตฌ๋ฌธ์์, color ๋ผ๋ ์ด ํด๋์ค์ ์กด์ฌํ๋ property ๋ง ์ด๊ธฐํํ๊ณ ,
// ์์ ๋ฐ์ numberOfWheels ๋ Vehicle ๊ฒ์ ๋ฐ๋ผ๊ฐ ๊ฒ์.
// ๊ทธ๋ ๋ค๋ฉด, super.init() ์ ์๋์ผ๋ก ํธ์ถ๋จ.
init(color: String) {
self.color = color
// super.init() implicitly called here
}
override var description: String {
return "\(super.description) in a beautiful \(color)"
}
}
Automatic init ์์
- ํ์ ํด๋์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ํด๋์ค์ init ์ ์์ํ์ง ์์ง๋ง,
- ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด ์์ํ๋ค.
- ํ์ ํด๋์ค๊ฐ designated init ์ ์ ์ํ์ง ์์ ๊ฒฝ์ฐ
์์ ํด๋์ค์ ์ง์ ๋ ๋ชจ๋ designated init ์์
- ํ์ ํด๋์ค๊ฐ designated init ์ ์ ์ํ์ง ์์ ๊ฒฝ์ฐ
- ํ์ ํด๋์ค๊ฐ ์์(super) ํด๋์ค์ designated init ์ ๋ชจ๋ ๊ตฌํํ ๊ฒฝ์ฐ (== ๊ท์น 1)
์๋์ผ๋ก ์ํผํด๋์ค์ convenience init์ ์ถ๊ฐํฉ๋๋ค
- ํ์ ํด๋์ค๊ฐ ์์(super) ํด๋์ค์ designated init ์ ๋ชจ๋ ๊ตฌํํ ๊ฒฝ์ฐ (== ๊ท์น 1)
์์ ํด๋์ค์ designated init ์ override ํ์ฌ ํ์ ํด๋์ค์ convenience init ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. (์ด๋ ๊ฒ ๊ตฌํํด๋ ๋ถ๋ชจ์ designated init ์ ๋ชจ๋ ๊ตฌํํ ๊ฒ์ด๋ฏ๋ก ๊ท์น 2๋ฅผ ๋ง์กฑ)
Designated, Convenience init ์ ๋์
Food > RecipeIngredient > ShoppingListItem ์ผ๋ก ์์๋๋ ํด๋์ค์ ์์๋ฅผ ๋ณผ ๊ฒ์.
class Food {
var name: String
// ํด๋์ค๋ memberwise init ์ด ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋์ง ์์ผ๋ฏ๋ก,
// designated init ์ ๊ตฌํํ๋ค.
// ๋ถ๋ชจ ํด๋์ค๊ฐ ์์ผ๋ฏ๋ก, super.init() ์ ๊ตฌํํ ํ์๊ฐ ์์.
init(name: String) {
self.name = name
}
// convenience init -> designated init
convenience init() {
self.init(name: "[Unnamed]")
}
}
let meat = Food(name: "Bacon")
let mystery = Food()
// Food ๋ฅผ ์์.
class RecipeIngredient: Food {
var quantity: Int
// designated init
init(name: String, quantity: Int) {
// ์์ ์ ๊ฒ 1 ์ถฉ์กฑ.
self.quantity = quantity // ์์์๋ง ์๋ ๊ฒ์ ๋จผ์ ์ด๊ธฐํํ๊ณ
super.init(name: name) // ๋ถ๋ชจ ์ด๊ธฐ์ ํธ์ถ.
}
// convenience init.
// Food ์ designated init ๊ณผ ๊ฐ์ ํ๋ผ๋ฏธํฐ. == override
override convenience init(name: String) {
self.init(name: name, quantity: 1)
}
}
// ๋ถ๋ชจ์ convenience init (๋ถ๋ชจ์ ๋ชจ๋ designated init ๊ตฌํํด์ ์๋ ์์)
let oneMysteryItem = RecipeIngredient()
// ๋ถ๋ชจ์ designated init ์ override ํ์ฌ convenience init ์ผ๋ก ๊ตฌํํจ.
let oneBacon = RecipeIngredient(name: "Bacon")
// ์์์ designated init
let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)
class ShoppingListItem: RecipeIngredient {
var purchased = false // ์ด๊ธฐํ ๊ตฌ๋ฌธ ๋์ ์ด๊ธฐ๊ฐ์ ๋ฃ์.
var description: String {
var output = "\(quantity) x \(name)"
output += purchased ? " โ" : " โ"
return output
}
// ์ด๊ธฐํ ๊ตฌ๋ฌธ์ด ์์ ์๊ธฐ ๋๋ฌธ์,
// ์์ ํด๋์ค์ ๋ชจ๋ designated init, convenience init ์ ์์.
}
// ์์๋ฐ์ 3๊ฐ์ง init ์ ๋ชจ๋ ์ฌ์ฉ๊ฐ๋ฅ.
var breakfastList = [
ShoppingListItem(),
ShoppingListItem(name: "Bacon"),
ShoppingListItem(name: "Eggs", quantity: 6),
]
breakfastList[0].name = "Orange juice"
breakfastList[0].purchased = true
for item in breakfastList {
print(item.description)
}
// 1 x Orange juice โ
// 1 x Bacon โ
// 6 x Eggs โ
6. Failable init โญ๏ธ
- ์คํจํ ์ ์๋ init
init?
- ์ ํจํ์ง ์์ ํ๋ผ๋ฏธํฐ ๊ฐ, ์ธ๋ถ ๋ฆฌ์์ค ๋ถ์ฌ, ... ์ ์ํด ์คํจํ ์ ์๋ค.
- ๋์ผํ ์ด๋ฆ๊ณผ ํ๋ผ๋ฏธํฐ๋ก ์คํจ ๊ฐ๋ฅ, ์คํจ ๋ถ๊ฐ๋ฅ ์ด๊ธฐํ๋ฅผ ์์ฑํ ์ ์๋ค.
- ์ด ๊ตฌ๋ฌธ์ด ์คํจํ๋ฉด ํด๋น ์ธ์คํด์ค๊ฐ nil ์ด ๋๋ค.
struct Animal {
let species: String
init?(species: String) {
// ์ด๊ธฐํ๊ฐ ์คํจํ๋ ์๊ฐ์ return nil ์ ํ๋ฉด ๋๋ค.
// ์ง์ง๋ก init ๊ตฌ๋ฌธ์ด nil ์ ๋ฐํํ๋ ๊ฒ์ ์๋๊ณ ,
// ์ด ๊ตฌ๋ฌธ์ด ์คํจํ๋ฉด ํด๋น ์ธ์คํด์ค๊ฐ nil ์ด ๋๋ค.
if species.isEmpty { return nil }
self.species = species
}
}
let anonymousCreature = Animal(species: "")
// anonymousCreature is of type Animal?, not Animal
if anonymousCreature == nil {
print("The anonymous creature could not be initialized")
}
// Prints "The anonymous creature could not be initialized"
Failable init for Enum
enum ์์๋ failable init ์ ์ฌ์ฉํ ์ ์๋ค.
enum TemperatureUnit {
case kelvin, celsius, fahrenheit
init?(symbol: Character) {
switch symbol {
case "K":
self = .kelvin
case "C":
self = .celsius
case "F":
self = .fahrenheit
default:
return nil
}
}
}
Failable init for Enum with Raw Values
- ์์๊ฐ์ด ์๋ enum ์ ์ ์ ํ ์์๊ฐ ํ์
์
rawValue
๋ผ๋ ํ๋ผ๋ฏธํฐ๋ก, - ์ผ์นํ๋ ์์๊ฐ์ ์ผ์ด์ค๊ฐ ์์ผ๋ฉด ํด๋น ์ผ์ด์ค๋ฅผ ์ ํ, ์์ผ๋ฉด nil ์ด ๋๋ ๊ธฐ๋ณธ failable init ์ ๊ฐ์ง๋ค.
enum TemperatureUnit: Character {
case kelvin = "K", celsius = "C", fahrenheit = "F"
}
let fahrenheitUnit = TemperatureUnit(rawValue: "F") // .kelvin
let unknownUnit = TemperatureUnit(rawValue: "X") // nil
Propagation of Initialization Failure
- ์คํจ ๊ฐ๋ฅํ ์ด๊ธฐํ ์ญ์ ๋ค๋ฅธ ์คํจ ๊ฐ๋ฅํ ์ด๊ธฐํ์ ์์ ๊ฐ๋ฅ.
- ํ์ ํด๋์ค์ ๊ฒ๋ ์์ ํด๋์ค๋ก ์์ ๊ฐ๋ฅ.
- ์คํจ๋๋ฉด ์ด๊ธฐํ ํ๋ก์ธ์ค ์ ์ฒด๊ฐ ์คํจ๋๊ณ ๋์ด์ ์ด๊ธฐํ ์ฝ๋๊ฐ ์คํ๋์ง ์๋๋ค.
class Product {
let name: String
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
class CartItem: Product {
let quantity: Int
init?(name: String, quantity: Int) {
if quantity < 1 { return nil }
self.quantity = quantity
super.init(name: name)
}
}
// quantity ๊ฐ 1 ๋ฏธ๋ง์ด๊ฑฐ๋ name ์ด ๋น ๊ฒ์ ๋ฃ๊ณ ์ด๊ธฐํํ๋ฉด ์คํจ.
Overriding a Failable Initializer
- ์คํจ ๊ฐ๋ฅํ ์ด๊ธฐ์๋ ํ์ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๊ฐ๋ฅํ๋ค.
- ์คํจ ๊ฐ๋ฅํ ์ด๊ธฐ์๋ฅผ ์ธ๋ํํ์ฌ ์คํจ ๋ถ๊ฐ๋ฅํ ์ด๊ธฐ์๋ก ์ฌ์ ์ ํ ์ ์์. ๋ฐ๋๋ ์๋จ.
class Document {
var name: String?
// this initializer creates a document with a nil name value
init() {}
// this initializer creates a document with a nonempty name value
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
class UntitledDocument: Document {
override init() {
// "" ์ผ๋ก ํธ์ถ๋์ง ์์ ๊ฒ์์ด ๋ณด์ฅ๋จ -> !
super.init(name: "[Untitled]")!
}
}
init!
- ์์์ ์ผ๋ก ์ธ๋ํ๋ Optional ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ failable init.
- init? <-> init! ์๋ก์๋ก ์์, ์ค๋ฒ๋ผ์ด๋๊ฐ ๊ฐ๋ฅํ๋ค.
- ํ์ง๋ง init -> init! ์ ์์ํ๋ฉด ์ด๊ธฐํ๊ฐ ์คํจํ๋ค.
7. Required init
- ๋ชจ๋ ํ์ ํด๋์ค๊ฐ ๊ตฌํํด์ผํ๋ ์ด๊ธฐํ ๊ตฌ๋ฌธ.
- ํ์ ํด๋์ค์์ override ํค์๋ ์ธ ํ์ ์๋ค.
- ์์๋ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ผ๋ก ์๊ตฌ์ฌํญ ์ถฉ์กฑ์ด ๊ฐ๋ฅํ๋ค๋ฉด, ๋ช ์์ ์ผ๋ก ๊ตฌํํ์ง ์์๋ ๋๋ค.
class SomeClass {
required init() {
// initializer implementation goes here
}
}
class SomeSubclass: SomeClass {
required init() {
// subclass implementation of the required initializer goes here
}
}
8. ํด๋ก์ ๋ฅผ ์ฌ์ฉํด์ ๊ธฐ๋ณธ ํ๋กํผํฐ ๊ฐ ์ค์ โญ๏ธ
- ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํ ๋, ํด๋ก์ ๋ ์ ์ญ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- ์ธ์คํด์ค๊ฐ ์ด๊ธฐํ ๋ ๋, ํด๋ก์ /ํจ์๊ฐ ํธ์ถ๋๊ณ , ๋ฐํ ๊ฐ์ด ํ๋กํผํฐ์ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ํ ๋น๋๋ค.
class VC: UIViewController {
let label: UILabel = {
let l = UILabel()
l.text= "text"
l.textColor = .blue
return l
}()
}
์์ฝ
- struct, enum, class ์ ์ด๊ธฐํ์์ ์ค์ํ ๊ฒ์
- ํด๋น ํ์ ์ด ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ stored property (์์๋ ๊ฒ ํฌํจ) ์ ์ด๊ธฐ๊ฐ์ด ๋ค์ด๊ฐ๋๊ฐ?
-> ๊ทธ๊ฒ์ ์ฌ์ฉ์๊ฐ ์ง์ ํ๊ธฐ ์ํด์ initializer๋ฅผ ์ ๊ณตํ๋๋ฐ...
- desingated init / convenience init ์ผ๋ก ์ด๋ฃจ์ด์ ธ์๊ณ ,
- ์๋์ฒ๋ผ convenience init ์ ๊ฐ์ class ์ desingated init ์ผ๋ก ์ด์ด์ ธ์ผํ๊ณ ,
- designated init ์ ์์ ํด๋์ค์ desingated init ์ ํธ์ถํ๋ค.
- ์ด ๋, ์์ ํ๊ฒ ์ด๊ธฐํ๋ฅผ ํ๊ธฐ ์ํด 2๋จ๊ณ ์ด๊ธฐํ๋ฅผ ์ํํ๊ฒ ๋๊ณ ,
- ๋ชจ๋ stored property ๊ฐ ํด๋น ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ class์ ์ํด ์ด๊ธฐํ ๋๊ณ ,
- ๊ฐ ํด๋์ค์ ์ ์ฅ๋ property ๋ฅผ custom
- ์ด ๋ ๋จ๊ณ์์ ์์ ์ฑ์ ํ๋ณดํ๊ธฐ ์ํด ์์ ์ฑ ๊ฒ์ฌ๋ฅผ ํ๊ฒ ๋๋ค.
์๋์ฒ๋ผ๋ง ์์ฑํด์ฃผ๋ฉด ๋ฌธ์ X!!
init() {
// ์์๋์ง ์์ ๋ชจ๋ ํ๋กํผํฐ ์ด๊ธฐํ
super.init() // ์์๋ ๊ฐ ์ค์ ๋จ
// ์์๋ฐ์ ๋ชจ๋ ํ๋กํผํฐ ์ด๊ธฐํ
}
convenience init() {
self.init() // designated init
// ์ด๊ธฐํ ํ๊ณ ์ถ์ ๊ฐ ์ด๊ธฐํ.
}
์ง๋ฌธ
Convinience init์ ๋ํด ์ค๋ช ํ์์ค.
- Convinience init ์ ํธ๋ฆฌํ ์ด๊ธฐํ๋ก, ๊ฐ์ ํด๋์ค ๋ด์ ์ ์๋ designated init ์ ํธ์ถํ ํ, ์ด๊ธฐํ ํ๊ณ ์ถ์ ๊ฐ์ ์ด๊ธฐํ ํ๋ ๊ตฌ๋ฌธ์ ์์ฑํ์ฌ ๊ตฌํํ๋ค.
- ๋ชจ๋ ์ด๊ธฐํ ๊ตฌ๋ฌธ์ ์ฌ๊ธฐ์ ์ฐ๋ ๊ฒ์ด ์๋๋ผ, ๋ค๋ฅธ init ์ ๋น๋ ค์ ์ด์ฉ.
- Convinience init ์ ๊ฐ์ ํด๋์ค ๋ด ๋ค๋ฅธ Convinience init ์ด๋ Designated init ์ ํธ์ถํ๋ฉฐ, ๊ถ๊ทน์ ์ผ๋ก๋ ๊ผญ Designated init ์ ํธ์ถํด์ผ ํ๋ค.
- ๋ง์ฝ, ํด๋์ค์ designated init ์ด ์๊ฑฐ๋, ์์ ํด๋์ค์ designated init ์ ๋ชจ๋ ๊ตฌํํด์ ์๋ฌต์ ์ผ๋ก ์์ ํด๋์ค์ init ์ด ๋ชจ๋ ์์๋๋ ๊ฒฝ์ฐ์, ์์ ํด๋์ค์ designated init ์ ํ์ ํด๋์ค์ convenience init ์ผ๋ก override ํ ์๋ ์๋ค.
์ฐธ๊ณ
https://bbiguduk.gitbook.io/swift/language-guide-1/initialization
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([Swift๐ฆฉ] #14 ์ด๊ธฐํ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@ddosang/Swift-14-์ด๊ธฐํ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค