returning - is swift
¿Cuál es la diferencia entre conveniencia init frente a init en ejemplos rápidos y explícitos mejor? (5)
Tengo problemas para comprender la diferencia entre ambos, o el propósito del inicio de conveniencia. Gracias
Aquí hay un ejemplo simple, tomado del portal de desarrolladores de Apple .
Básicamente, el inicializador designado es
init(name: String)
, se asegura de que todas las propiedades almacenadas se inicialicen.
El
init()
conveniencia
init()
, sin tomar argumentos, establece automáticamente el valor de la propiedad almacenada del
name
en
[Unnamed]
mediante el inicializador designado.
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]"
Es útil, cuando se trata de clases grandes, con al menos algunas propiedades almacenadas. Recomendaría leer más sobre las opciones y la herencia en el portal de desarrolladores de Apple.
Los inicializadores de conveniencia se usan cuando tienes alguna clase con muchas propiedades que hace que sea "doloroso" inicializar siempre con todas esas variables, así que lo que haces con el inicializador de conveniencia es que solo pasas algunas de las variables para inicializar el objeto y asigne el resto con un valor predeterminado. Hay un muy buen video en el sitio web de Ray Wenderlich, no estoy seguro de que sea gratis o no porque tengo una cuenta paga. Aquí hay un ejemplo donde puedes ver que en lugar de inicializar mi objeto con todas esas variables, solo le estoy dando un título.
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
Nota: Lea todo el texto
Los inicializadores designados son los inicializadores principales para una clase. Un inicializador designado inicializa completamente todas las propiedades introducidas por esa clase y llama a un inicializador de superclase apropiado para continuar el proceso de inicialización hasta la cadena de superclase.
Los inicializadores de conveniencia son secundarios y admiten inicializadores para una clase. Puede definir un inicializador de conveniencia para llamar a un inicializador designado de la misma clase que el inicializador de conveniencia con algunos de los parámetros del inicializador designado predeterminados.
Los inicializadores designados para las clases se escriben de la misma manera que los inicializadores simples para los tipos de valor:
init(parameters) {
statements
}
Los inicializadores de conveniencia están escritos en el mismo estilo, pero con el modificador de conveniencia colocado antes de la palabra clave init, separados por un espacio:
convenience init(parameters) {
statements
}
Un ejemplo práctico son los siguientes:
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”
El inicializador init (name: String) de la clase Food se proporciona como un inicializador designado porque garantiza que todas las propiedades almacenadas de una nueva instancia de Food se inicialicen por completo. La clase Food no tiene una superclase, por lo que el inicializador init (name: String) no necesita llamar a super.init () para completar su inicialización.
“La clase Food también proporciona un inicializador de conveniencia, init (), sin argumentos. El inicializador init () proporciona un nombre de marcador de posición predeterminado para un nuevo alimento al delegar en init (name: String) de la clase Food con un valor de nombre de [Sin nombre]: "
“let mysteryMeat = Food()
// mysteryMeat''s name is "[Unnamed]”
La segunda clase en la jerarquía es una subclase de Food llamada RecipeIngredient. La clase RecipeIngredient modela un ingrediente en una receta de cocina. Introduce una propiedad Int llamada cantidad (además de la propiedad de nombre que hereda de Food) y define dos inicializadores para crear instancias de RecipeIngredient:
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)
}
}
La clase RecipeIngredient tiene un único inicializador designado, init (nombre: Cadena, cantidad: Int), que se puede utilizar para completar todas las propiedades de una nueva instancia de RecipeIngredient. Este inicializador comienza asignando el argumento de cantidad pasada a la propiedad de cantidad, que es la única propiedad nueva introducida por RecipeIngredient. Después de hacerlo, el inicializador delega al inicializador init (name: String) de la clase Food.
página: 536 Extracto de: Apple Inc. "El lenguaje de programación Swift (Swift 4)". iBooks. https://itunes.apple.com/pk/book/the-swift-programming-language-swift-4-0-3/id881256329?mt=11
Por lo tanto, resulta útil cuando no necesita especificar todas y cada una de las propiedades de una clase. Entonces, por ejemplo, si quiero crear todas las aventuras con un valor inicial de HP de 100, usaría este siguiente init de conveniencia y solo agregaría un nombre. Esto reducirá mucho el código.
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)
}
}
init
estándar:
Los inicializadores designados son los inicializadores principales para una clase. Un inicializador designado inicializa completamente todas las propiedades introducidas por esa clase y llama a un inicializador de superclase apropiado para continuar el proceso de inicialización en la cadena de superclase.
convenience init
:
Los inicializadores de conveniencia son secundarios y admiten inicializadores para una clase. Puede definir un inicializador de conveniencia para llamar a un inicializador designado de la misma clase que el inicializador de conveniencia con algunos de los parámetros del inicializador designado configurados a valores predeterminados. También puede definir un inicializador de conveniencia para crear una instancia de esa clase para un caso de uso específico o tipo de valor de entrada.
según la Initialization
Básicamente, todo esto significa, en pocas palabras, que utiliza un inicializador conveniente para hacer que llamar a un inicializador designado sea más rápido y más "conveniente".
Por lo tanto, los inicializadores de conveniencia requieren el uso de
self.init
lugar de algo como el
super.init
que vería en una anulación de un inicializador designado.
ejemplo de pseudocódigo:
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)
}
Los uso mucho al crear vistas personalizadas y con inicializadores largos que tienen valores predeterminados principalmente. Los documentos hacen un mejor trabajo explicando que yo, ¡échales un vistazo!