Swift์—์„œ Struct, Class, Enum์„ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” Initializer์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž. ์ด ๋ถ€๋ถ„์—์„œ class ์ดˆ๊ธฐํ™”๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์ดˆ๊ธฐํ™” ๊ณผ์ •๊ณผ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด ์žˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์€ ์ข€ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์–ด ๋‹ค์Œ ํฌ์ŠคํŒ…์œผ๋กœ ๋„˜๊ฒผ๋‹ค. ์ด๋ฒˆ์—๋Š” Value type, Reference type์˜ ์ดˆ๊ธฐํ™” ๊ณผ์ •์— ๋Œ€ํ•ด ๊ฐœ๊ด„์ ์ด ๋‚ด์šฉ์„ ์•Œ์•„๋ณด๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•œ๋‹ค. ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•˜์ž.

outline

  • class, struct, enum ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • stored property ์ดˆ๊ธฐํ™” ๋ฐ instance ์‚ฌ์šฉ ์œ„ํ•œ ์ดˆ๊ธฐํ™”

  • initailier๋ผ๋Š” method ์‚ฌ์šฉ

  • return value ์—†์Œ

    • Objective-C์˜ ๊ฒฝ์šฐ ์žˆ์Œ
  • class์˜ ๊ฒฝ์šฐ init, deinit์„ ์Œ์œผ๋กœ ๊ฐ€์ง

  • Optional Property์˜ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐํ™”ํ•  ํ•„์š” ์—†์Œ

    • nil๋กœ ์ดˆ๊ธฐํ™”
  • Constant(let) Property๋Š” initialization ๊ณผ์ •์—์„œ ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐํ™” ๋˜์–ด์•ผ ํ•จ

    • ์ดํ›„ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€
  • struct์˜ ๊ฒฝ์šฐ, init์„ ๋”ฐ๋กœ ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ memberwise initializer๊ฐ€ ๋งŒ๋“ค์–ด์ง

  • failable initializer

    • init?์œผ๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•จ
    • ์ž˜๋ชป๋œ parameter๋‚˜ ์™ธ๋ถ€ resource๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
    • override ํ•ด์„œ non-failable initializer๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ
      class Document {
          var name: String?
          init() {}
          init?(name: String) {
              if name.isEmpty { return nil }
              self.name = name
          }
      }
       
      class AutomaticallyNamedDocument: Document {
          override init(name: String) {
              super.init()
              if name.isEmpty {
                  self.name = "[untitled]"
              } else {
                  self.name = name
              }
          }
      }
  • Closure๋ฅผ ํ†ตํ•œ default property value setting์ด ๊ฐ€๋Šฅํ•จ

    • class, struct ๊ฐ€๋Šฅ
    class SomeClass {
        let someProperty: SomeType = {
            // setting
            return someValue
        }
    }

Value Type Initialization

struct Size {
    var width = 0.0, height = 0.0
}
 
let a = Size(width: 3, height: 4)
let b = Size(width: 10)
 
print(a.width, a.height)
print(b.width, b.height)
  • Struct์˜ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ memberwise initailizer๋ฅผ ๊ฐ–๋Š”๋‹ค.
  • ์ด๊ฒŒ ๋ญ๋ƒ
    • ์ปค์Šคํ…€ ์ƒ์„ฑ์ž๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ์— ์ง€๊ฐ€ ์•Œ์•„์„œ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ
    • ์ฒ˜์Œ์— ๊ฐ’์„ ์ง€์ •ํ•ด์คฌ์„ ๋•Œ์—๋„ ๋™์ž‘,
    • ์ด๋ฏธ ๊ฐ’์„ ์ง€์ •ํ•ด์คฌ๋‹ค๋ฉด ํŠน์ • ํ”„๋กœํผํ‹ฐ๋งŒ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ
struct Point {
    var x = 0.0, y = 0.0
}
 
struct Rect {
    var origin = Point() // 0.0, 0.0
    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)
    }
}
  • ์œ„์—์„œ๋Š” ๋ช…์‹œ๋œ ์ƒ์„ฑ์ž๊ฐ€ ์—†์„ ๋–„, ํ”„๋กœํผํ‹ฐ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ์–ด Size()๋„ ์ƒ์„ฑ์ด ๋˜์—ˆ์ง€๋งŒ
  • ์ง€๊ธˆ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ init์„ ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด, ์ถ”๊ฐ€์ ์œผ๋กœ ์„ ์–ธ๋˜์ง€ ์•Š๋Š”๋‹ค.
    • ์ฆ‰ Rect()๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ
    • ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ถ”๊ฐ€์ ์œผ๋กœ ์„ ์–ธํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

Class Initialization

  • ๋ชจ๋“  stored property๋Š” initilization๊ณผ์ •์—์„œ ์ดˆ๊ธฐํ™”๋˜์–ด์•ผ ํ•จ

  • ์ƒ์† ๊ด€๊ณ„์˜ ๋ชจ๋“  superclass๋„ ๋งˆ์ฐฌ๊ฐ€์ง€

  • ์ด๋Ÿฌํ•œ ์ƒ์† ๊ด€๊ณ„์—์„œ ์—ญ์‹œ ๋ชจ๋“  property๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋‘๊ฐ€์ง€ ํ˜•ํƒœ์˜ initializer๋ฅผ ๊ฐ€์ง

    • Designated initializer
      • Primary initializer
      • ๋ชจ๋“  property๋ฅผ ์ดˆ๊ธฐํ™” ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•จ
      • Superclass์˜ property๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด super์˜ init์„ ์‚ฌ์šฉ
      • ๋ชจ๋“  class๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ง€๋ช… ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง
      • ๋ณดํ†ต 1๊ฐœ์ž„

    Convenience initializer

    • Secondary initializer
    • ์ผ๋ถ€ property์—์„œ default๊ฐ’์„ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉ
    • ๋‚ด๋ถ€์—์„œ designated intializer๋ฅผ ํ˜ธ์ถœํ•จ
    • ํŠน์ • usecase์—์„œ ์‚ฌ์šฉ๋  ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ
      convenience init(parameters) {
          //statements
      }

Delegation Rule

  • Designated initializer๋Š” ๋ฐ˜๋“œ์‹œ ์œ„ super์˜ designated initializer๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•จ
  • convinience initializer๋Š” ๋ฐ˜๋“œ์‹œ ๊ทธ class์˜ ๋‹ค๋ฅธ initializier๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•จ
  • convenience intializer๋Š” ์ตœ์ข…์ ์œผ๋กœ designatied initializer๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜•ํƒœ์–ด์•ผ ํ•จ

Two-Phase Initialization

  • Phase 1
    • initializer ํ˜ธ์ถœ๋จ
    • ์ƒˆ๋กœ์šด instance๋ฅผ ์œ„ํ•œ memory๊ฐ€ alloc๋จ
      • memory ์ดˆ๊ธฐํ™”๋Š” ์•„์ง์ž„
    • designated intiailizer๊ฐ€ ๋ชจ๋“  stored property์— ๋Œ€ํ•œ ์ดˆ๊ธฐํ™” ์ง„ํ–‰
    • designated initializer๊ฐ€ super class์˜ initializer๋ฅผ ํ˜ธ์ถœ
    • root class๊นŒ์ง€ ๋ฐ˜๋ณต ํ˜ธ์ถœ
    • ๋ชจ๋“  stored property๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  phase 1 ์ข…๋ฃŒ
  • Phase 2
    • root class๋กœ๋ถ€ํ„ฐ ์—ญ์œผ๋กœ ์ˆ˜ํ–‰
    • ๋ชจ๋“  class๋Š” instance๋ฅผ customizerํ•  ์ˆ˜ ์žˆ์Œ
    • self์— accessํ•˜๊ณ , property ์ˆ˜์ •ํ•˜๊ณ , instance method ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  • ๋ณด๋‹ค ์ž์„ธํ•œ ์„ค๋ช…์€ ๋‹ค์Œ ๊ธ€์— ์ž‘์„ฑํ•˜๋„๋ก ํ•˜๊ฒ ์Œ
  • ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ์ด์œ ๋Š”, ๋ชจ๋“  stored property๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ๊ทธ ๋‹ค์Œ์— ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•จ์ž„

require initializer

  • ๋ชจ๋“  subclass๋“ค์ด ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” initializer
  • required ์‚ฌ์šฉ
  • overriding์‹œ์—๋„ required ์‚ฌ์šฉํ•ด์•ผ ํ•จ