Latest web development tutorials

proceso de construcción Swift

Proceso de construcción es utilizar una instancia de una clase, estructura o tipo de enumeración llevado a cabo el proceso de preparación. Este proceso implica el establecimiento de valores iniciales para cada atributo y la instancia para la preparación y ejecución de las tareas de inicialización necesarios.

Swift init constructor () método.

Y Objective-C en diferentes constructor, el constructor Swift no tiene que devolver un valor, su tarea principal es asegurar que la nueva instancia se completa antes del primer uso inicialización adecuada.

instancias de clases pueden definirse destructor (deinitializer) Memoria de trabajo de limpieza antes de la liberación instancia de clase.


La asignación inicial de la propiedad de tipo de almacenamiento

Las clases y estructuras cuando se crea una instancia, debe establecer el valor inicial apropiado para todos los atributos de tipo de almacenamiento.

Al almacenar asignación de propiedad en el constructor, sus valores se fijan directamente y no incumple cualquier observador propiedad.

Almacenamiento proceso de asignación de propiedad en el constructor:

  • La creación de valor inicial.

  • En la definición del atributo especifica los valores de las propiedades por defecto.

  • Inicializa una instancia, y llama al método init ().


constructor

El constructor se llama cuando se crea una nueva instancia de un tipo particular. Su forma más simple es similar a un método de instancia sin ningún parámetro, el nombre de inicio de palabras clave.

gramática

init()
{
    // 实例化后执行的代码
}

Ejemplos

La siguiente estructura define el inicio de un constructor sin argumentos, y dentro de la longitud del atributo de tipo de almacenamiento y ancho del valor de inicialización de 6 y 12:

struct rectangle {
    var length: Double
    var breadth: Double
    init() {
        length = 6
        breadth = 12
    }
}
var area = rectangle()
print("矩形面积为 \(area.length*area.breadth)")

La salida por encima de la ejecución del programa es:

矩形面积为 72.0

Los valores de propiedad predeterminados

Podemos establecer los valores iniciales de la propiedad de tipo de almacenamiento en el constructor; también, puede establecer un valor predeterminado cuando una declaración de propiedad.

Se le permite usar el limpiador constructor por defecto, más clara, y puede inferirse automáticamente por el atributo de tipo de valor predeterminado.

El siguiente ejemplo queremos establecer el valor por defecto cuando una declaración de propiedad:

struct rectangle {
	// 设置默认值
    var length = 6
    var breadth = 12
}
var area = rectangle()
print("矩形的面积为 \(area.length*area.breadth)")

La salida por encima de la ejecución del programa es:

矩形面积为 72

Los parámetros de configuración

Se puede definir el constructor proporcionado el parámetro constructor init (), de la siguiente manera:

struct Rectangle {
    var length: Double
    var breadth: Double
    var area: Double
    
    init(fromLength length: Double, fromBreadth breadth: Double) {
        self.length = length
        self.breadth = breadth
        area = length * breadth
    }
    
    init(fromLeng leng: Double, fromBread bread: Double) {
        self.length = leng
        self.breadth = bread
        area = leng * bread
    }
}

let ar = Rectangle(fromLength: 6, fromBreadth: 12)
print("面积为: \(ar.area)")

let are = Rectangle(fromLeng: 36, fromBread: 12)
print("面积为: \(are.area)")

La salida por encima de la ejecución del programa es:

面积为: 72.0
面积为: 432.0

nombre del parámetro interno y externo

Funciones y métodos con los mismos parámetros, los parámetros estructurales también hay el nombre de un parámetro en el constructor para uso interno y externo nombres de los parámetros utilizados cuando se invoca un constructor.

Sin embargo, la configuración no es como antes de que haya un nombre reconocible corchetes como funciones y métodos. Así que llame al constructor, el constructor está determinada principalmente por la necesidad de llamar a los nombres de los parámetros del constructor y tipos.

Si usted no proporciona argumentos cuando se define el nombre externo constructor, Swift generará automáticamente un nombre con el mismo nombre interno externo para cada parámetro de constructor.

struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }
}

// 创建一个新的Color实例,通过三种颜色的外部参数名来传值,并调用构造器
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)

print("red 值为: \(magenta.red)")
print("green 值为: \(magenta.green)")
print("blue 值为: \(magenta.blue)")

// 创建一个新的Color实例,通过三种颜色的外部参数名来传值,并调用构造器
let halfGray = Color(white: 0.5)
print("red 值为: \(halfGray.red)")
print("green 值为: \(halfGray.green)")
print("blue 值为: \(halfGray.blue)")

La salida por encima de la ejecución del programa es:

red 值为: 1.0
green 值为: 0.0
blue 值为: 1.0
red 值为: 0.5
green 值为: 0.5
blue 值为: 0.5

Sin nombre parámetro externo

Si no desea proporcionar nombre externo para un parámetro del constructor, puede utilizar un guión bajo _ para describir su nombre de visualización externo.

struct Rectangle {
    var length: Double
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    //不提供外部名字
    init(_ area: Double) {
        length = area
    }
}

// 调用不提供外部名字
let rectarea = Rectangle(180.0)
print("面积为: \(rectarea.length)")

// 调用不提供外部名字
let rearea = Rectangle(370.0)
print("面积为: \(rearea.length)")

// 调用不提供外部名字
let recarea = Rectangle(110.0)
print("面积为: \(recarea.length)")

La salida por encima de la ejecución del programa es:

面积为: 180.0
面积为: 370.0
面积为: 110.0

Atributos opcionales Tipo

Si su tipo personalizado contiene un argumento lógico para permitir atributos de tipo de almacenamiento vacías, es necesario definir como un tipo opcional opcional Tipo (tipo de atributo opcional).

Al almacenar declaración de propiedad es opcional, se inicializará automáticamente a cero vacía.

struct Rectangle {
    var length: Double?
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    
    init(_ area: Double) {
        length = area
    }
}

let rectarea = Rectangle(180.0)
print("面积为:\(rectarea.length)")

let rearea = Rectangle(370.0)
print("面积为:\(rearea.length)")

let recarea = Rectangle(110.0)
print("面积为:\(recarea.length)")

La salida por encima de la ejecución del programa es:

面积为:Optional(180.0)
面积为:Optional(370.0)
面积为:Optional(110.0)

Modificar proceso de construcción Propiedad constante

Justo antes del final del proceso de construcción puede determinar el valor de una constante, puede cambiar el valor de los atributos constantes en cualquier momento del proceso de construcción.

Para una instancia de clase, su atributo constante sólo puede definirse en su clase modificaciones en el proceso de construcción; no se puede cambiar en una subclase.

A pesar de la propiedad de longitud es ahora es una constante, aún podemos establecer su valor en el constructor de su clase:

struct Rectangle {
    let length: Double?
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    
    init(_ area: Double) {
        length = area
    }
}

let rectarea = Rectangle(180.0)
print("面积为:\(rectarea.length)")

let rearea = Rectangle(370.0)
print("面积为:\(rearea.length)")

let recarea = Rectangle(110.0)
print("面积为:\(recarea.length)")

La salida por encima de la ejecución del programa es:

面积为:Optional(180.0)
面积为:Optional(370.0)
面积为:Optional(110.0)

El constructor por defecto

El constructor por defecto, simplemente crear todos los valores de las propiedades se ajustan a la instancia predeterminada:

Los ejemplos siguientes, todas las propiedades de la clase ShoppingListItem tiene un valor por defecto, y no es el padre de la clase base, se obtendrá automáticamente una puede establecer valores predeterminados para todas las propiedades del constructor por defecto

class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()


print("名字为: \(item.name)")
print("数理为: \(item.quantity)")
print("是否付款: \(item.purchased)")

La salida por encima de la ejecución del programa es:

名字为: nil
数理为: 1
是否付款: false

Cada miembro de la estructura constructora

Si la estructura de todas las propiedades de tipo de almacenamiento proporcionan valores por defecto y no proporciona su propio constructor personalizado, que reciben de forma automática cada miembro de un constructor.

Cuando llamamos a cada miembro de la constructora, mediante la realización de los valores tradicionales y los miembros del mismo nombre de parámetro de nombre de atributo para completar la asignación inicial de las propiedades de miembro.

El ejemplo siguiente define una estructura rectangular, que contiene dos atributos longitud y anchura. Swift se puede asignar de acuerdo con la inicial de 100,0 estas dos propiedades, 200,0 derivan automáticamente su tipo Double.

struct Rectangle {
    var length = 100.0, breadth = 200.0
}
let area = Rectangle(length: 24.0, breadth: 32.0)

print("矩形的面积: \(area.length)")
print("矩形的面积: \(area.breadth)")

Dado que las propiedades de dos de almacenamiento tienen valores por defecto, las estructuras del rectángulo automáticamente un miembro de cada constructor de init (anchura: altura :). Se puede utilizar para crear una nueva instancia de rectángulo.

La salida por encima de la ejecución del programa es:

名字为: nil
矩形的面积: 24.0
矩形的面积: 32.0

Agente de tipo constructor de valor

Constructor llamando a otros constructores para completar parte de la instancia del proceso de construcción. Este proceso se denomina agente de estructura, que puede reducir la duplicación de código entre varios constructores.

Los siguientes ejemplos, estructura llamada Rect proceso de construcción y tamaño de punto de:

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)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}


// origin和size属性都使用定义时的默认值Point(x: 0.0, y: 0.0)和Size(width: 0.0, height: 0.0):
let basicRect = Rect()
print("Size 结构体初始值: \(basicRect.size.width, basicRect.size.height) ")
print("Rect 结构体初始值: \(basicRect.origin.x, basicRect.origin.y) ")

// 将origin和size的参数值赋给对应的存储型属性
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
    size: Size(width: 5.0, height: 5.0))

print("Size 结构体初始值: \(originRect.size.width, originRect.size.height) ")
print("Rect 结构体初始值: \(originRect.origin.x, originRect.origin.y) ")


//先通过center和size的值计算出origin的坐标。
//然后再调用(或代理给)init(origin:size:)构造器来将新的origin和size值赋值到对应的属性中
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
    size: Size(width: 3.0, height: 3.0))

print("Size 结构体初始值: \(centerRect.size.width, centerRect.size.height) ")
print("Rect 结构体初始值: \(centerRect.origin.x, centerRect.origin.y) ")

La salida por encima de la ejecución del programa es:

Size 结构体初始值: (0.0, 0.0) 
Rect 结构体初始值: (0.0, 0.0) 
Size 结构体初始值: (5.0, 5.0) 
Rect 结构体初始值: (2.0, 2.0) 
Size 结构体初始值: (3.0, 3.0) 
Rect 结构体初始值: (2.5, 2.5) 

Constructor reglas de proxy

Tipo valor Tipo de la clase
No es compatible con la herencia, por lo que el proceso es agente de estructura relativamente simple, ya que otros agentes que puedan único constructor de proveerse. Puede utilizar la referencia self.init otro constructor que pertenece al mismo tipo de valor en un constructor personalizado. Se puede heredar de otras clases, lo que significa que la clase tiene la responsabilidad de garantizar la totalidad de sus propiedades heredadas cuando la estructura de tipo de almacenamiento puede ser inicializado correctamente.

La herencia y la construcción proceso de la clase

Swift ofrece dos tipos de constructor de la clase para asegurar que todas las instancias de las propiedades de clase de almacenamiento se pueden obtener en los valores iniciales, que se especifican constructor y constructor de conveniencia.

Especifica el constructor constructor de conveniencia
El constructor de la clase principal Clase relativamente menor, constructor asistida
Todos los bienes se ofreció la clase inicializado y llama al constructor de la clase padre sobre la base de la cadena principal de lograr la inicialización de la clase padre. Se puede definir constructor de conveniencia para llamar a la misma clase que se especifique en el constructor, y proporciona valores predeterminados para los parámetros. También puede definir constructor de conveniencia de crear una instancia de un propósito particular o insumos específicos.
Cada clase debe tener al menos un constructor especificado Sólo cuando sea necesario para facilitar el constructor de la clase
Init(parameters) {
    statements
}
convenience init(parameters) {
      statements
}

Especifica el constructor de instancias

class mainClass {
    var no1 : Int // 局部存储变量
    init(no1 : Int) {
        self.no1 = no1 // 初始化
    }
}
class subClass : mainClass {
    var no2 : Int // 新的子类存储变量
    init(no1 : Int, no2 : Int) {
        self.no2 = no2 // 初始化
        super.init(no1:no1) // 初始化超类
    }
}

let res = mainClass(no1: 10)
let res2 = subClass(no1: 10, no2: 20)

print("res 为: \(res.no1)")
print("res2 为: \(res2.no1)")
print("res2 为: \(res2.no2)")

La salida por encima de la ejecución del programa es:

res 为: 10
res 为: 10
res 为: 20

Ejemplos de constructor de conveniencia

class mainClass {
    var no1 : Int // 局部存储变量
    init(no1 : Int) {
        self.no1 = no1 // 初始化
    }
}

class subClass : mainClass {
    var no2 : Int
    init(no1 : Int, no2 : Int) {
        self.no2 = no2
        super.init(no1:no1)
    }
    // 便利方法只需要一个参数
    override convenience init(no1: Int)  {
        self.init(no1:no1, no2:0)
    }
}
let res = mainClass(no1: 20)
let res2 = subClass(no1: 30, no2: 50)

print("res 为: \(res.no1)")
print("res2 为: \(res2.no1)")
print("res2 为: \(res2.no2)")

La salida por encima de la ejecución del programa es:

res 为: 20
res2 为: 30
res2 为: 50

Herencia y constructor de sobrecarga

Swift subclase no hereda el constructor predeterminado de la clase padre.

El constructor de la clase padre se hereda sólo en el caso de la determinación y la seguridad.

Al sustituir un constructor de la clase padre específico, tiene que escribir un modificador de anulación.

class SuperClass {
    var corners = 4
    var description: String {
        return "\(corners) 边"
    }
}
let rectangle = SuperClass()
print("矩形: \(rectangle.description)")

class SubClass: SuperClass {
    override init() {  //重载构造器
        super.init()
        corners = 5
    }
}

let subClass = SubClass()
print("五角型: \(subClass.description)")

La salida por encima de la ejecución del programa es:

矩形: 4 边
五角型: 5 边

Especifica los ejemplos de constructores y constructores de conveniencia

El siguiente ejemplo demostrará la operación especificada en el constructor, constructores y facilitar la herencia constructor automático.

Contiene dos clases MainClass jerarquía de clases, la subclase definidos, y demostrar cómo su interacción constructores.

class MainClass {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    convenience init() {
        self.init(name: "[匿名]")
    }
}
let main = MainClass(name: "w3big")
print("MainClass 名字为: \(main.name)")

let main2 = MainClass()
print("没有对应名字: \(main2.name)")

class SubClass: MainClass {
    var count: Int
    init(name: String, count: Int) {
        self.count = count
        super.init(name: name)
    }
    
    override convenience init(name: String) {
        self.init(name: name, count: 1)
    }
}

let sub = SubClass(name: "w3big")
print("MainClass 名字为: \(sub.name)")

let sub2 = SubClass(name: "w3big", count: 3)
print("count 变量: \(sub2.count)")

La salida por encima de la ejecución del programa es:

MainClass 名字为: w3big
没有对应名字: [匿名]
MainClass 名字为: w3big
count 变量: 3

El constructor de la clase puede fallar

Si una clase, objeto, estructura o tipo de enumeración, es posible estructurar sí en el proceso falla, la falta de definición de un constructor.

inicialización de variables fallidos razones posibles son:

  • Valor de parámetro no válido entrante.

  • Faltan algunos recursos externos necesarios.

  • Que no cumplía con ciertas condiciones.

Con el fin de manejar adecuadamente el caso de este proceso de configuración puede fallar.

Puede en una definición de tipo de clase, o enumeración de la estructura, añadir uno o constructor más fracasado. La sintaxis es un signo de interrogación después de la palabra clave init Jiatian (init?).

Ejemplos

En el siguiente ejemplo, la definición de una estructura llamada animal, que ha llamado la especie, el tipo de atributo de cadena constantes.

Mientras tanto, la estructura también define una con una especie de parámetro de tipo cadena puede fallar constructor. El constructor puede fallar, se usa para verificar si el argumento pasado a una cadena vacía, una cadena vacía, el constructor puede fallar, la falta de construcción de un objeto, de lo contrario el éxito.

struct Animal {
    let species: String
    init?(species: String) {
        if species.isEmpty { return nil }
        self.species = species
    }
}

//通过该可失败构造器来构建一个Animal的对象,并检查其构建过程是否成功
// someCreature 的类型是 Animal? 而不是 Animal
let someCreature = Animal(species: "长颈鹿")

// 打印 "动物初始化为长颈鹿"
if let giraffe = someCreature {
    print("动物初始化为\(giraffe.species)")
}

La salida por encima de la ejecución del programa es:

动物初始化为长颈鹿

tipo enumerado constructor puede fallar

Usted puede con uno o más parámetros pueden ser configurados por el constructor no pudo conseguir un miembros de la enumeración específicos del tipo enumerado.

Ejemplos

En el siguiente ejemplo, la definición de un tipo enumerado nombrado TemperatureUnit. Que contiene tres posibles miembro de enumeración (Kelvin, Celsius, y Fahrenheit) y un fracaso puede ser usado para encontrar los valores constructor de caracteres correspondientes miembros de la enumeración:

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
        }
    }
}


let fahrenheitUnit = TemperatureUnit(symbol: "F")
if fahrenheitUnit != nil {
    print("这是一个已定义的温度单位,所以初始化成功。")
}

let unknownUnit = TemperatureUnit(symbol: "X")
if unknownUnit == nil {
    print("这不是一个已定义的温度单位,所以初始化失败。")
}

La salida por encima de la ejecución del programa es:

这是一个已定义的温度单位,所以初始化成功。
这不是一个已定义的温度单位,所以初始化失败。

El constructor de la clase puede fallar

Los tipos de valor (tales como estructuras o tipo enumerado) pueden fallar constructor, cuándo y dónde desencadenar la construcción no sin ninguna limitación de este comportamiento.

Sin embargo, el constructor de la clase puede fallar y el agente sólo puede llamar al constructor de entre todas las clases se produjo en todas las propiedades de la clase se inicializan después de comportamiento de fallo de encendido.

Ejemplos

Por ejemplo, la definición de una clase llamada StudRecord porque la propiedad studname es una constante, por lo que una vez que el éxito constructor de la clase StudRecord, propiedad studname debe tener un valor distinto de cero.

class StudRecord {
    let studname: String!
    init?(studname: String) {
        self.studname = studname
        if studname.isEmpty { return nil }
    }
}
if let stname = StudRecord(studname: "失败构造器") {
    print("模块为 \(stname.studname)")
}

La salida por encima de la ejecución del programa es:

模块为 失败构造器

Cubriendo un constructor puede fallar

Al igual que otros constructores, como, también puede anular el constructor de la clase base puede fallar con el constructor de la subclase puede fallar.

También puede reemplazar por un constructor de la clase base pueden fallar con el fracaso de la subclase no constructor.

Puede utilizar un constructor que no ha fallado que cubre un constructor puede fallar, pero a su vez, no se ha solucionado.

Un constructor que no ha fallado nunca puede llamar un agente puede fallar constructor.

Ejemplos

El siguiente ejemplo describe un fracaso y no fallo Constructor:

class Planet {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    convenience init() {
        self.init(name: "[No Planets]")
    }
}
let plName = Planet(name: "Mercury")
print("行星的名字是: \(plName.name)")

let noplName = Planet()
print("没有这个名字的行星: \(noplName.name)")

class planets: Planet {
    var count: Int
    
    init(name: String, count: Int) {
        self.count = count
        super.init(name: name)
    }
    
    override convenience init(name: String) {
        self.init(name: name, count: 1)
    }
}

La salida por encima de la ejecución del programa es:

行星的名字是: Mercury
没有这个名字的行星: [No Planets]

Puede fallar init constructor!

En general, se añade un signo de interrogación después de la forma de palabras clave de inicio (init?) Posible incapacidad para definir un constructor, pero también se puede utilizar el init mediante la adición de un signo de exclamación después de la manera de definir un constructor fallado (init!) . Ejemplos son los siguientes:

struct StudRecord {
    let stname: String
    
    init!(stname: String) {
        if stname.isEmpty {return nil }
        self.stname = stname
    }
}

let stmark = StudRecord(stname: "w3big")
if let name = stmark {
    print("指定了学生名")
}

let blankname = StudRecord(stname: "")
if blankname == nil {
    print("学生名为空")
}

La salida por encima de la ejecución del programa es:

指定了学生名
学生名为空