Latest web development tutorials

Swift процесс строительства

Процесс строительства использовать экземпляр класса, структуры или типа перечисления осуществляется процесс подготовки. Этот процесс включает в себя установку начальных значений для каждого атрибута и экземпляр для подготовки и выполнения необходимых задач инициализации.

Swift конструктор инициализации () метод.

И Objective-C в различных конструктор, конструктор Swift не нужно возвращать значение, их главная задача состоит в том, чтобы гарантировать, что новый экземпляр завершается перед первым использованием правильной инициализации.

Экземпляры классов могут быть определены деструктор (deinitializer) памяти работу по наведению порядка, прежде чем экземпляр класса освобождается.


Первоначальное назначение объекта хранения типа

Классы и структуры при создании экземпляра, он должен установить соответствующее начальное значение для всех атрибутов хранения типа.

При сохранении задания свойств в конструкторе, их значения устанавливаются непосредственно и не вызывает каких-либо свойств наблюдателя.

Процесс присвоения имущества хранения в конструкторе:

  • Создание начального значения.

  • В определении атрибута определяет значения свойств по умолчанию.

  • Инициализирует экземпляр, и вызывает метод инициализации ().


конструктор

Конструктор вызывается при создании нового экземпляра определенного типа. Его простая форма похожа на метод экземпляра без каких-либо параметров, имя инициализации ключевых слов.

грамматика

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

примеров

Следующая структура определяет Init конструктор без аргументов, так и внутри длины атрибута типа хранения и широты значение инициализации 6 и 12:

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

Выход выше выполнение программы:

矩形面积为 72.0

Значения свойств по умолчанию

Мы можем установить начальные значения для свойства хранения типа в конструкторе; Кроме того, можно установить значение по умолчанию при объявлении свойства.

Это позволяет использовать уборщика конструктор по умолчанию, более четким, и может автоматически вывести атрибутом типа значения по умолчанию.

В следующем примере мы хотим установить значение по умолчанию при объявлении свойства:

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

Выход выше выполнение программы:

矩形面积为 72

параметры конфигурации

Вы можете определить конструктор при условии параметр конструктора инициализации () следующим образом:

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)")

Выход выше выполнение программы:

面积为: 72.0
面积为: 432.0

Внутреннее и внешнее имя параметра

Функции и методы с теми же параметрами, структурные параметры существуют также имя параметра в конструктор для внутреннего использования и имен внешних параметров, используемых при вызове конструктора.

Тем не менее, конфигурация не является, как и прежде есть узнаваемое имя в скобках, как функции и методы. Так вызовите конструктор, конструктор определяется главным образом необходимостью называть имена параметров конструктора и типов.

Если вы не предоставляете аргументы при определении внешнего имени конструктора, Swift будет автоматически генерировать имя с тем же внешним внутренним именем для каждого параметра конструктора.

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)")

Выход выше выполнение программы:

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

Отсутствие внешнего имени параметра

Если вы не хотите , чтобы обеспечить внешнее имя для параметра конструктора, вы можете использовать подчеркивание _ , чтобы описать его имя внешнего дисплея.

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)")

Выход выше выполнение программы:

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

Дополнительные атрибуты Тип

Если ваш пользовательский тип содержит логический аргумент, чтобы разрешить пустые атрибуты для хранения типа, необходимо определить его как дополнительный тип дополнительного типа (необязательный атрибут типа).

При хранении декларации имущества не является обязательным, оно будет автоматически инициализируются пустой ноль.

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)")

Выход выше выполнение программы:

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

Изменить процесс строительства Свойство константы

Незадолго до окончания процесса строительства можно определить значение константы, вы можете изменить значение постоянных атрибутов в любой момент в процессе строительства.

Для экземпляра класса, его неизменный атрибут может быть определен только в его модификации строительного процесса класса, не может быть изменен в подклассе.

Несмотря на свойство длина теперь является постоянной величиной, мы можем установить его значение в конструкторе своего класса:

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)")

Выход выше выполнение программы:

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

Конструктор по умолчанию

Конструктор по умолчанию будет просто создать все значения свойств устанавливаются к экземпляру по умолчанию:

Следующие примеры, все свойства ShoppingListItem класс имеет значение по умолчанию, и он не является отцом базового класса, он будет автоматически получить можно установить значения по умолчанию для всех свойств конструктора по умолчанию

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


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

Выход выше выполнение программы:

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

Каждый член структуры конструктора

Если структура всех свойств хранения типа обеспечивают значения по умолчанию и не предоставляют свои собственные пользовательские строитель, они автоматически получают каждый член конструктора.

Когда мы называем каждому члену конструктора, выполняя традиционные ценности и члены одного и того же имени параметра имя атрибута завершить начальное назначение свойств членов.

Следующий пример определяет структуру Rectangle, который содержит длину два атрибута и ширину. Swift может быть назначено в соответствии с первоначальным 100.0 этих двух свойств, 200,0 автоматически получают их тип 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)")

Поскольку свойства двух устройств хранения будут иметь значения по умолчанию, структуры Прямоугольник автоматически членом каждого конструктора Init (ширина: высота :). Вы можете использовать его, чтобы создать новый экземпляр Rectangle.

Выход выше выполнение программы:

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

Значение конструктор типа агента

Конструктор, вызвав другие конструкторы, чтобы завершить часть экземпляра процесса строительства. Этот процесс называется структура агента, он может уменьшить дублирование кода между несколькими конструкторами.

Ниже приведены примеры, Rect структура называется процесс строительства и точка Площадь:

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) ")

Выход выше выполнение программы:

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) 

правила Конструктор прокси

Тип Значение Тип класса
Он не поддерживает наследование, поэтому процесс является относительно простой структурой агент, в качестве других агентов они могут только конструктор, чтобы обеспечить себя. Вы можете использовать эталонный self.init другой конструктор, принадлежащий к тому же типу значения в пользовательский конструктор. Он может наследовать от других классов, что означает, что класс имеет ответственность за обеспечение всех своих наследственных свойств, когда структура хранения типа может быть правильно инициализирован.

Наследование и построение процесса класса

Swift предоставляет два типа конструктора класса, чтобы гарантировать, что все экземпляры свойств класса хранения могут быть получены в начальные значения, которые указаны конструктор и удобство конструктора.

Определяет конструктор Удобство конструктор
Главный конструктор класса Класс относительно небольшим, при помощи конструктора
Все имущество инициализируется класс предложил и вызвать конструктор родительского класса на основе родительской цепи для достижения инициализации родительского класса. Можно определить удобный конструктор для вызова один и тот же класс, как указано в конструкторе, а также предоставляет значения параметров по умолчанию. Можно также определить удобство конструктор для создания экземпляра определенной цели или конкретные материалы.
Каждый класс должен иметь, по крайней мере, указанный конструктор Только тогда, когда необходимо, чтобы облегчить конструктор класса
Init(parameters) {
    statements
}
convenience init(parameters) {
      statements
}

Определяет конструктор экземпляра

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)")

Выход выше выполнение программы:

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

Примеры удобства конструктора

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)")

Выход выше выполнение программы:

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

Наследование и конструктор перегрузки

Swift суб-класс не наследует конструктор по умолчанию родительского класса.

Конструктор родительского класса наследуется только в определении дела и безопасности.

Когда вы переопределить заданный родительский класс конструктор, вам нужно написать модификатор переопределения.

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)")

Выход выше выполнение программы:

矩形: 4 边
五角型: 5 边

Определяет примеры конструктора и удобство конструкторы

В следующем примере показана работа, указанным в конструкторе, конструкторов и облегчить автоматическое наследование конструктора.

Она содержит два класса, определенные MainClass, иерархия классов SubClass, и продемонстрировать, как их взаимодействие конструкторов.

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)")

Выход выше выполнение программы:

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

Конструктор класса может потерпеть неудачу

Если класс, объект, структура или тип перечисления, можно структурировать себя в процесс терпит неудачу, невозможность определить конструктор.

Ошибка инициализации переменной Возможные причины:

  • Входящий недопустимое значение параметра.

  • Отсутствуют какие-то внешние ресурсы, необходимые.

  • Это не отвечают определенным условиям.

Для того чтобы правильно обрабатывать случай этого процесса конфигурации может выйти из строя.

Вы можете в определении типа класса или перечислений структуры, добавить один или несколько неудачной конструктор. Синтаксис является знак вопроса после инициализации ключевого слова Jiatian (INIT?).

примеров

В следующем примере, определение структуры под названием Animal, который назвал вид, тип атрибута Строка констант.

В то же время, структура также определяет с вида параметров типа Строка может не конструктор. Конструктор может потерпеть неудачу, используется для проверки является ли аргумент, переданный в пустую строку, пустой строкой, конструктор может потерпеть неудачу, неспособность построить объект, в противном случае успеха.

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

Выход выше выполнение программы:

动物初始化为长颈鹿

Перечислимый конструктор типа может потерпеть неудачу

Вы можете с одним или несколькими параметрами могут быть сконфигурированы с помощью конструктора не удалось, чтобы получить конкретные элементы перечисления перечисляемого типа.

примеров

В следующем примере, определение перечислимого типа имени TemperatureUnit. Который содержит три возможных перечислимую члена (Кельвина, Цельсия и Фаренгейта) и отказ может быть использован для нахождения значений конструктора символов, соответствующие элементы перечисления:

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("这不是一个已定义的温度单位,所以初始化失败。")
}

Выход выше выполнение программы:

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

Конструктор класса может потерпеть неудачу

Типы значений (такие как структуры или перечисляемого типа) может произойти сбой конструктора, когда и где, чтобы вызвать строительство не может без каких-либо ограничений этого поведения.

Тем не менее, конструктор класса может потерпеть неудачу, и агент может вызывать только конструктор среди всех классов произошло во всех свойств класса инициализируются после того, как поведение неисправности системы зажигания.

примеров

К примеру, определение класса называется StudRecord, потому что studname свойство является постоянным, поэтому, как только конструктор класса StudRecord успеха, studname свойство должно иметь значение не-ноль.

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

Выход выше выполнение программы:

模块为 失败构造器

Покрытие конструктор может потерпеть неудачу

Как и другие конструкторы, как, вы можете также переопределить конструктор базового класса может потерпеть неудачу с конструктором подкласса может выйти из строя.

Кроме того, можно переопределить с помощью конструктора базового класса может потерпеть неудачу с отказом, не конструктор подкласса.

Вы можете использовать не-конструктор не удалось, охватывающую конструктор может потерпеть неудачу, но, в свою очередь, он не работает.

Не-неудачная конструктор никогда не может вызвать агента может произойти сбой конструктора.

примеров

В следующем примере описывается недостаточность и безотказную Конструктора:

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

Выход выше выполнение программы:

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

Может произойти сбой конструктора инициализации!

Как правило, мы добавляем знак вопроса после ключевого слова инициализации (способ инициализации?) Может не определить конструктор, но вы также можете использовать инициализации, добавив восклицательный знак после способ определения неисправного конструктор (INIT!) , Примерами могут служить следующие:

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("学生名为空")
}

Выход выше выполнение программы:

指定了学生名
学生名为空