init와 init의 편리함의 차이는 무엇입니까? 더 빠르고 명확한 예에서 init가 더 낫습니다.
는 둘하는 데 을 겪고 .convenience init.
표.init:
지정된 이니셜라이저는 클래스의 기본 이니셜라이저입니다.지정된 초기화자는 해당 클래스에 의해 도입된 모든 속성을 완전히 초기화하고 적절한 슈퍼클래스 초기화자를 호출하여 슈퍼클래스 체인에서 초기화 프로세스를 계속합니다.
convenience init:
편의 이니셜라이저는 클래스의 이니셜라이저를 지원하는 보조 기능입니다.지정된 이니셜라이저의 매개 변수 중 일부가 기본값으로 설정된 상태에서 편의 이니셜라이저와 동일한 클래스의 지정된 이니셜라이저를 호출하도록 편의 이니셜라이저를 정의할 수 있습니다.또한 편의 이니셜라이저를 정의하여 특정 사용 사례 또는 입력 값 유형에 대해 해당 클래스의 인스턴스를 만들 수 있습니다.
Swift Documentation에 따라
즉, 편의 이니셜라이저를 사용하여 지정된 이니셜라이저를 더 빠르고 "편리하게" 호출할 수 있습니다.따라서 편의성 이니셜라이저는 다음과 같은 용도로 사용해야 합니다.self.init super.init지정된 이니셜라이저의 오버라이드에서 볼 수 있습니다.
의사 코드 예제:
init(param1, param2, param3, ... , paramN) {
// code
}
// can call this initializer and only enter one parameter,
// set the rest as defaults
convenience init(myParamN) {
self.init(defaultParam1, defaultParam2, defaultParam3, ... , myParamN)
}
기본값이 주로 포함된 긴 이니셜라이저가 있는 사용자 정의 보기 등을 만들 때 많이 사용합니다.의사들이 저보다 설명을 더 잘 해요, 확인해 보세요!
편의 이니셜라이저는 속성이 많은 클래스가 있을 때 사용되며, 이로 인해 항상 모든 변수로 위트를 초기화하는 것이 "고통스럽다"고 할 수 있습니다. 따라서 편의 이니셜라이저를 사용하면 일부 변수를 전달하여 개체를 초기화하고 나머지 변수는 기본값으로 할당할 수 있습니다.Ray Wenderlich 웹사이트에 매우 좋은 비디오가 있는데, 제가 유료 계정을 가지고 있기 때문에 무료인지 아닌지 확실하지 않습니다.예를 들어, 이 모든 변수를 사용하여 개체를 초기화하는 대신 제목을 지정하는 것을 볼 수 있습니다.
struct Scene {
var minutes = 0
}
class Movie {
var title: String
var author: String
var date: Int
var scenes: [Scene]
init(title: String, author: String, date: Int) {
self.title = title
self.author = author
self.date = date
scenes = [Scene]()
}
convenience init(title:String) {
self.init(title:title, author: "Unknown", date:2016)
}
func addPage(page: Scene) {
scenes.append(page)
}
}
var myMovie = Movie(title: "my title") // Using convenicence initializer
var otherMovie = Movie(title: "My Title", author: "My Author", date: 12) // Using a long normal initializer
편의성 이니셜라이저가 기본 파라미터 값을 설정하는 경우
나를 위해.convenience initializers클래스 속성의 기본값을 설정하는 것 이상의 작업이 있는 경우 유용합니다.
init()가 지정된 클래스 구현
그렇지 않으면 기본값을 설정하기만 하면 됩니다.init정의(예:
class Animal {
var race: String // enum might be better but I am using string for simplicity
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4) {
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
}
}
편의성이 있는 클래스 확장()
그러나 단순히 기본값을 설정하는 것 외에 더 많은 작업이 있을 수 있습니다.convenience initializers유용하게 사용할 수 있습니다.
extension Animal {
convenience init(race: String, name: String) {
var legs: Int
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
} else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
사용 예
// default init with all default values used
let myFirstDog = Animal(name: "Bello")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider", name: "Itzy")
// default init with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// convenience init with Fatal error: Race AlienSpecies needs to be implemented!!
let myFault = Animal(race: "AlienSpecies", name: "HelloEarth")
다음은 Apple Developer 포털에서 가져온 간단한 예입니다.
는 기적으이이는저라니입니다.init(name: String)저장된 모든 속성이 초기화됩니다.
그init()합니다.name을 에된재산장에 했습니다.[Unnamed]지정된 이니셜라이저를 사용합니다.
class Food {
let name: String
// MARK: - designated initializer
init(name: String) {
self.name = name
}
// MARK: - convenience initializer
convenience init() {
self.init(name: "[Unnamed]")
}
}
// MARK: - Examples
let food = Food(name: "Cheese") // name will be "Cheese"
let food = Food() // name will be "[Unnamed]"
대용량 클래스를 처리할 때 최소한 몇 개의 저장된 속성을 사용하면 유용합니다.Apple Developer 포털에서 옵션 및 상속에 대한 자세한 내용을 읽어보는 것이 좋습니다.
편의 초기화자는 클래스 확장에 정의될 수 있습니다.하지만 표준적인 것은 - 할 수 없습니다.
사용 사례가 다음과 같은 경우에 적합합니다.
- 같은 클래스의 다른 이니셜라이저에서 이니셜라이저를 호출합니다.
- 유형을 확장하여 고유한 사용자 정의 초기화 프로그램을 생성하려는 경우.
같은 클래스의 다른 이니셜라이저에서 이니셜라이저를 호출합니다.
놀이터에서 해보세요.
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
init(name: String) {
self.init(name: name, level: 0) //<- Call the initializer above?
//Sorry you can't do that. How about adding a convenience keyword?
}
}
Player(name:"LoseALot")
편리성 키워드 포함
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
//Add the convenience keyword
convenience init(name: String) {
self.init(name: name, level: 0) //Yes! I am now allowed to call my fellow initializer!
}
}
유형을 확장하여 고유한 사용자 정의 초기화 프로그램을 생성하려는 경우.
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
}
extension Player {
convenience init(name: String) {
self.init(name: name, level: 0)
}
}
그자리의 convenience init값이 있는 클래스를 선택적으로 초기화할 수 있습니다.
참고: 전체 텍스트 읽기
지정된 이니셜라이저는 클래스의 기본 이니셜라이저입니다.지정된 초기화자는 해당 클래스에 의해 도입된 모든 속성을 완전히 초기화하고 적절한 슈퍼클래스 초기화자를 호출하여 슈퍼클래스 체인까지 초기화 프로세스를 계속합니다.
편의 이니셜라이저는 클래스의 이니셜라이저를 지원하는 보조 기능입니다.지정된 이니셜라이저의 매개 변수 중 일부를 기본값으로 설정한 상태에서 편의 이니셜라이저와 동일한 클래스의 지정된 이니셜라이저를 호출하도록 편의 이니셜라이저를 정의할 수 있습니다.
클래스의 지정된 이니셜라이저는 값 유형의 단순 이니셜라이저와 동일한 방식으로 작성됩니다.
init(parameters) {
statements
}
편의 이니셜라이저는 동일한 스타일로 작성되지만 init 키워드 앞에 편의 수식어를 공백으로 구분하여 배치합니다.
convenience init(parameters) {
statements
}
실용적인 예는 다음과 같습니다.
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”
Food 클래스의 init(이름: String) 이니셜라이저는 새 Food 인스턴스의 저장된 모든 속성이 완전히 초기화되도록 보장하기 때문에 지정된 이니셜라이저로 제공됩니다.Food 클래스에 수퍼 클래스가 없으므로 init(이름: String) 이니셜라이저가 super.init()를 호출하여 초기화를 완료할 필요가 없습니다.
"또한 Food 클래스는 인수 없이 편리한 이니셜라이저 init()를 제공합니다.init() 이니셜라이저는 이름 값이 [Unnamed]인 식품 클래스의 init(이름: String)에 위임하여 새 식품에 대한 기본 자리 표시자 이름을 제공합니다.
“let mysteryMeat = Food()
// mysteryMeat's name is "[Unnamed]”
계층 구조의 두 번째 클래스는 RecipeInderent라고 불리는 음식의 하위 클래스입니다.레시피 재료 클래스는 요리 레시피의 재료를 모델링합니다.여기에는 (Food에서 상속하는 이름 속성 외에) 수량이라는 Int 속성이 도입되고 RecipeIngent 인스턴스를 생성하기 위한 두 개의 이니셜라이저가 정의됩니다.
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)
}
}
RecipeIngedient 클래스에는 새 RecipeIngent 인스턴스의 모든 속성을 채우는 데 사용할 수 있는 단일 지정 이니셜라이저 init(이름: String, 수량: Int)가 있습니다.이 이니셜라이저는 전달된 수량 인수를 RecipeIngent에서 도입한 유일한 새 속성인 수량 속성에 할당하는 것으로 시작합니다.이렇게 하면 이니셜라이저는 Food 클래스의 init(이름: String) 이니셜라이저까지 위임합니다.
페이지:536 발췌: Apple Inc."스위프트 프로그래밍 언어(스위프트 4)" 아이북스https://itunes.apple.com/pk/book/the-swift-programming-language-swift-4-0-3/id881256329?mt=11
모든 답변이 좋은 것 같지만 간단한 예를 들어 이해해 보겠습니다.
class X{
var temp1
init(a: Int){
self.temp1 = a
}
이제, 우리는 클래스가 다른 클래스를 상속받을 수 있다는 것을 알고 있습니다.
class Z: X{
var temp2
init(a: Int, b: Int){
self.temp2 = b
super.init(a: a)
}
이 경우 클래스 Z에 대한 인스턴스를 만드는 동안 'a'와 'b' 값을 모두 제공해야 합니다.
let z = Z(a: 1, b: 2)
그러나 b의 값만 전달하고 나머지 값이 다른 값을 사용하도록 하려면 다른 값을 초기화해야 합니다.하지만 어떻게 기다려요? 그러기 위해서는 수업 전에만 잘 설정해야 합니다.
//This is inside the class Z, so consider it inside class Z's declaration
convenience init(b: Int){
self.init(a: 0, b: b)
}
convenience init(){
self.init(a: 0, b: 0)
}
이제 변수에 대한 일부 값, 모두 값 또는 없음 값을 제공하여 클래스 Z의 인스턴스를 만들 수 있습니다.
let z1 = Z(b: 2)
let z2 = Z()
따라서 클래스에 대한 각 속성을 지정할 필요가 없을 때 유용합니다.예를 들어, 제가 시작 HP 값이 100인 모든 모험을 만들고 싶다면, 다음과 같은 편의성을 사용하여 이름을 추가할 것입니다.이것은 코드를 많이 줄일 것입니다.
class Adventure {
// Instance Properties
var name: String
var hp: Int
let maxHealth: Int = 100
// Optionals
var specialMove: String?
init(name: String, hp: Int) {
self.name = name
self.hp = hp
}
convenience init(name: String){
self.init(name: name, hp: 100)
}
}
@Chris Graf 예제에 대해 2점을 더 추가하고 싶습니다 ---
클래스는 선언 또는 "init" 메서드에서 저장된 모든 속성(옵션을 초기화할 필요가 없음)을 초기화해야 합니다.편리함은 기본 초기화 위에서 작동합니다. 기본 초기화를 호출하기 전에 또는 기본 초기화 후에 추가 설정을 추가합니다.
"편리한" 이니셜라이저의 장점
1. "편의성 init"에 의해 구현되는 동일한 기능은 init(/-속성이 두 개뿐인 init 2) 방법으로도 달성할 수 있지만, 기본 init(/-속성이 모두 있는 init 1)을 사용하는 대신 모든 속성을 다시 초기화해야 합니다.그 이유는 "init" 메서드가 "self.init"을 호출할 수 없기 때문입니다. 인수의 수가 다르더라도 말입니다.그래서, 코드 복제가 있을 것입니다.
2.기본 이니셜라이저에서도 추가 설정을 수행할 수 있습니다.그러나 일부 시나리오에서는 저장된 속성만 초기화하고 다른 시나리오에서는 추가 설정을 수행하려면 두 가지 다른 초기화 프로그램이 필요할 수 있습니다.그러나 위와 같이 2개의 코드가 다르게 선언되면 다시 2개의 코드로 작성을 종료하겠습니다.따라서 둘 다 필요한 경우 "편의성" init을 사용하고, 추가 설정을 사용하여 init(편의성 init)을 사용하고, 저장된 속성 초기화만 사용하여 init를 실행합니다.
참고:편의성 init: 항상 default init를 호출해야 합니다.Convenience를 호출하면 클래스 인스턴스가 초기화되지 않기 때문입니다.따라서 "self.init()"를 호출하기 전에 "convince init"에서 "self"에 액세스할 수 없습니다.
class Animal {
var race: String
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4)
{//—init 1
`enter code here`with all properties
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
print("came to init 1")
}
init(race: String, name: String) {//—init 2 with only two properties)
var legs = 0
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
}
legCount = legs
self.race = race
self.name = name
print("came to init 2")
}
convenience init(race: String) {
print("came to convenience init")
var legs = 0
let name = "default"
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
}
else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
// default init1 with all default values used
let myFirstDog = Animal(name: "Bello")
// default init1 with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// default init2 with 2 parameters
let myOctopus1 = Animal(race:"Octopus1" , name:"Octocat1")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider")
간단히 말해 편의성 이니셜라이저
- 고유한 서명으로 함수에 오버로드됩니다.
- 지정된 init 함수에 유연성을 제공합니다.
- 클래스 속성에 기본값을 제공하는 기능을 제공합니다.
- 클래스에 많은 위트가 있을 수 있지만 모든 위트는 지정된 init 함수에 위임해야 합니다.
언급URL : https://stackoverflow.com/questions/40093484/what-is-the-difference-between-convenience-init-vs-init-in-swift-explicit-examp
'programing' 카테고리의 다른 글
| 의 최대 가능 길이는 얼마입니까?NET 문자열? (0) | 2023.05.16 |
|---|---|
| 마케팅 아이콘 누락 (0) | 2023.05.16 |
| Pillow를 사용하여 png을 JPEG로 변환 (0) | 2023.05.16 |
| 윈도우에서 커피스크립트? (0) | 2023.05.16 |
| 명령줄에서 데이터베이스 만들기 (0) | 2023.05.16 |

