νμ ν΄λμ€λ μΌλ°μ μΌλ‘ μμ ν΄λμ€μ μμ±μλ₯Ό μμνμ§ μλλ€.
κ·Έλ¬λ, νΉμ 쑰건μμλ μλμΌλ‘ μμλλ€.
νμ ν΄λμ€μμ μ§μ μμ±μλ₯Ό μ μνμ§ μλ κ²½μ°, μμ ν΄λμ€μ μ§μ μμ±μλ₯Ό μλμΌλ‘ μμνλ€.
νμ ν΄λμ€κ° Rule 1μ λ°λ₯΄κ±°λ νμ ν΄λμ€μμ μμ ν΄λμ€μ λͺ¨λ μ§μ μμ±μλ₯Ό ꡬννλ©΄ μμ ν΄λμ€μ κ°νΈ μμ±μλ₯Ό μλμΌλ‘ μμνλ€.
β μ΄ κ·μΉλ€μ νμ ν΄λμ€μ κ°νΈ μμ±μλ₯Ό μΆκ°ν΄λ μ μ©λλ€.
μμ μ€λͺ μμ
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
let namedMeat = Food(name: "Bacon")
// namedMeat's name is "Bacon"
let mysteryMeat = Food()
// mysteryMeat's name is "[Unnamed]"
- κ°νΈ μμ±μκ° μ§μ μμ μλ₯Ό delegate across
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int) {
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, quantity: 1)
}
}
let oneMysteryItem = RecipeIngredient()
let oneBacon = RecipeIngredient(name: "Bacon")
let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)
-
μ§μ μμ±μκ° Safety Check 1μ λ§μ‘±
π‘ Safety check 1: μμ ν΄λμ€μ μμ±μλ₯Ό νΈμΆνκΈ°μ μ ν΄λΉ ν΄λμ€μ λͺ¨λ νλ‘νΌν°κ° μ΄κΈ°νλμ΄μΌ ν¨ -
κ°νΈ μμ±μμ 맀κ°λ³μκ° μμ ν΄λμ€μ μ§μ μμ±μμ λκ°κΈ° λλ¬Έμ overrideλ‘ μμ±
-
κ°νΈ μμ±μκ° μ§μ μμ±μλ₯Ό delegate across
-
μμ ν΄λμ€μ μ§μ μμ±μλ₯Ό λͺ¨λ ꡬννκΈ° λλ¬Έμ, μμ ν΄λμ€μ κ°νΈ μμ±μλ₯Ό μλμΌλ‘ μμ
- μ΄ κ°νΈ μμ±μλ Food λ²μ κ³Ό λμΌνκ² κΈ°λ₯νμ§λ§, νμ ν΄λμ€μ init(name)μ delegate across
class ShoppingListItem: RecipeIngredient {
var purchased = false
var description: String {
var output = "\(quantity) x \(name)"
output += purchased ? " β" : " β"
return output
}
}
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 β
- νμ ν΄λμ€μμ μ§μ ν΄λμ€λ₯Ό μ§μ νμ§ μκΈ° λλ¬Έμ μμ ν΄λμ€μ μ§μ μμ±μμ κ°νΈ μμ±μλ₯Ό λͺ¨λ μλμΌλ‘ μμ
- μ΄κΈ°νκ° μ€ν¨ν μ μμ λ μ¬μ©νλ©΄ μ μ©νλ€.
- init? νμμΌλ‘ μ¬μ©
- failable μμ±μμ non-failable μμ±μμ ν¨λ¬λ―Έν°μ μ΄λ¦μ΄ κ°μ μ μλ€.
- failable μμ±μλ μ΄κΈ°ννλ νμ μ optional valueλ₯Ό μμ±νλ€.
- μ€ν¨κ° μμλλ μ§μ μ
return nil
λ₯Ό μ¬μ©νλ€.- μμ±μλ κ°μ λ°ννμ§ μλλ€. μ€ν¨λ₯Ό λνλ΄κΈ° μν΄ nilμ μ¬μ©νμ§λ§, μ΄κΈ°νκ° μ±κ³΅νμ λ return ν€μλλ₯Ό μ¬μ©νμ§ μλλ€.
let wholeNumber: Double = 12345.0
let pi = 3.14159
if let valueMaintained = Int(exactly: wholeNumber) {
print("\(wholeNumber) conversion to Int maintains value of \(valueMaintained)")
}
// Prints "12345.0 conversion to Int maintains value of 12345"
let valueChanged = Int(exactly: pi)
// valueChanged is of type Int?, not Int
if valueChanged == nil {
print("\(pi) conversion to Int doesn't maintain value")
}
// Prints "3.14159 conversion to Int doesn't maintain value"
- enumμΌλ‘ μ¬μ©ν λ νμ© κ°λ₯
- μ΄κ±° λͺ©λ‘μ μμ κ²½μ° μ΄κΈ°ν μ€ν¨ (enum nil λ°ν)
- raw valueλ‘ μ΄κΈ°ννλ enumμ μλμΌλ‘ failable μμ±μλ₯Ό μμ νλ€.
- μΌμΉ κ°μ΄ μμΌλ©΄ μ΄κΈ°ν μ€ν¨λ₯Ό νΈλ¦¬κ±°
- failable μμ±μ(ν΄λμ€, μ€νΈλμ³, μ΄λ ν¬ν¨)λ λ€λ₯Έ failable μμ±μμκ² delegate across κ°λ₯
- νμ ν΄λμ€μ failable μμ±μλ μμ ν΄λμ€μ failable μμ±μμκ² delegate up κ°λ₯
β μ΄λ€ κ²½μ°λ μ΄κΈ°νκ° μ€ν¨νλ©΄ μ΄κΈ°ν νλ‘μΈμ€ μ μ²΄κ° μ¦μ μ€ν¨νκ³ λ μ΄μμ μ΄κΈ°ν μ½λκ° μ§νλμ§ μλλ€.
failable μμ±μλ non-failable μμ±μμκ² delegate κ°λ₯ non-failableν κΈ°μ‘΄ μ΄κΈ°ν νλ‘μΈμ€μ μ μ¬μ μΈ μ€ν¨ μνλ₯Ό μΆκ°ν΄μΌ νλ κ²½μ° μ¬μ©
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)
}
}
- CartItemμ μ΄κΈ°ν μ€ν μ λ μ€ νλλΌλ μ΄κΈ°νλ₯Ό μ€ν¨νλ©΄ μ 체 μ΄κΈ°ν νλ‘μΈμ€ μ¦μ μ€ν¨
- μμ ν΄λμ€μ failable μμ±μλ₯Ό νμ ν΄λμ€κ° override κ°λ₯
-
μμ ν΄λμ€μ failable μμ±μλ₯Ό νμ ν΄λμ€κ° non-failable μμ±μλ‘ override κ°λ₯
β μ΄λ₯Ό ν΅ν΄, μμ ν΄λμ€μ μ΄κΈ°νκ° μ€ν¨ν΄λ μ€ν¨ν μ μλ νμ ν΄λμ€ μμ±μλ₯Ό μ μν μ μλ€.
- μ΄ κ²½μ°λ₯Ό λ§μ‘± μν¬ μ μΌν λ°©λ²μ μμ ν΄λμ€ failable μμ±μλ₯Ό κ°μ λ‘ unwrapνλ κ²μ΄λ€.
-
μμ λ΄μ©μ κ°λ₯νμ§λ§ λ°λμ κ²½μ°(non-failable μμ±μλ₯Ό failable μμ±μλ‘ overrideνλ κ²)μ λΆκ°λ₯
-
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 AutomaticallyNamedDocument: Document {
override init() {
super.init()
self.name = "[Untitled]"
}
override init(name: String) {
super.init()
if name.isEmpty {
self.name = "[Untitled]"
} else {
self.name = name
}
}
}
- μμ ν΄λμ€μ μ§μ μμ±μλ₯Ό λͺ¨λ override
- μμ ν΄λμ€μ failable μμ±μλ₯Ό non-failable μμ±μλ‘ override
class UntitledDocument: Document {
override init() {
super.init(name: "[Untitled]")!
}
}
-
κ°μ unwrappingμΌλ‘ non-failable μμ±μλ‘ μμ
-
μμ ν΄λμ€μ init(name:) μμ±μμ λΉ λ¬Έμμ΄μ΄ λ€μ΄κ° κ²½μ°, λ°νμμλ¬ λ°μ
β νμ μ€ν¨νμ§ μλλ‘ λ§€κ°λ³μλ₯Ό μ¬μ©ν΄μ€μΌ νλ€.
- Optionalμ΄ μλ failable μμ±μλ₯Ό λ§λ€κ³ μΆμ λ μ¬μ©
- init! νμ
- init? β init!, init! β init? : delegate, override κ°λ₯
- init β init! : delegateν μ μμ§λ§, init!μ΄ μ€ν¨νλ€λ©΄ assertionμ trigger νλ€.
-
μ΄λ€ ν΄λμ€μ λͺ¨λ νμ ν΄λμ€κ° μμ±μλ₯Ό νμμ μΌλ‘ ꡬννκ² νκ³ μΆμ λ μ¬μ©
-
required
ν€μλ μ¬μ©- μ°μμ μΌλ‘ λ°μν νμ ν΄λμ€μ μ΄ μμ±μλ₯Ό νμλ‘ κ΅¬νν΄μΌ ν¨μ μ리기 μν΄ required ν€μλλ₯Ό μ¬μ©ν΄μΌ νλ€.
-
override
ν€μλλ μ¬μ© X -
μμλ μμ±μλ₯Ό μ¬μ©νμ¬ μΆ©μ‘±ν μ μμΌλ©΄, νμ μμ±μλ₯Ό λͺ μμ μΌλ‘ ꡬνν νμ μλ€.
β μΆ©μ‘±: λͺ¨λ μ μΈν νλ‘νΌν°λ₯Ό μ΄κΈ°ννλ κ²
protocol JSONInitializable { // Use Encoders, but just for example
init(fromJSON: String)
}
class Foo: JSONInitializable {
let x: Int
// "required" is necessary because this init is required for the
// conformance to JSONInitializable
required init(fromJSON json: String) {
//...
x = 123 //some value from the JSON
}
}
class Baz: Foo {
// `init(fromJSON json: String)` can be inherited,
// so it's implicitly defined for Baz, as well as Foo.
}
class Bar: Foo {
// The presence of this uninitialized constant `y` requires an
// a value in the declaration, or an initializer that sets it
let y: Int
// Since we didn't specify a value for `y` in its declaration,
// this initializer must be explicitly specified so as to initialize `y`.
// Doing so blocks the inheritance of `init(fromJSON json: String)` from
// the super class, and requires us to define it ourselves,
// in order to preserve conformance to `JSONInitializable`
required init(fromJSON json: String) {
//...
y = 0
super.init(fromJSON: json)
}
}
- μ μ₯ νλ‘νΌν°μ default κ°μ μ€μ μ΄ νμν κ²½μ°, ν΄λ‘μ λλ μ μ ν¨μλ₯Ό μ¬μ©ν μ μλ€.
class SomeClass {
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
}
- ()λ ν΄λ‘μ λ₯Ό μ¦μ μ€ννκ² νλ©°, μμ κ²½μ° ν΄λ‘μ μ체λ₯Ό νλ‘νΌν°μ ν λΉνλ€.
- ν΄λ‘μ κ° μ€νλλ μμ μ λλ¨Έμ§ μΈμ€ν΄μ€λ μμ§ μ΄κΈ°νκ° λμ§ μμκΈ° λλ¬Έμ μ κ·Ό ν μ μλ€.
- selfμ μΈμ€ν΄μ€ λ©μλ νΈμΆ λΆκ°λ₯
https://docs.swift.org/swift-book/LanguageGuide/Initialization.html