Latest web development tutorials

Swift proces budowy

Proces budowlany jest użycie instancji klasy, struktury lub typu wyliczenia przeprowadzonego procesu przygotowania. Proces ten polega na ustawieniu wartości początkowych dla każdego atrybutu i przykład do przygotowania i realizacji niezbędnych zadań inicjujących.

Metoda Swift konstruktor init ().

I Objective-C w inny konstruktor, konstruktor Swift nie musi zwracać wartość, a ich głównym zadaniem jest zapewnienie, że nowa instancja zostanie zakończona przed pierwszym użyciem prawidłowej inicjalizacji.

instancje klasy mogą być zdefiniowane destructor (deinitializer) Pamięć prac porządkowych przed instancją klasy zostanie zwolniony.


Początkowy przydział nieruchomości magazynowo-type

Klasy i struktury gdy instancja jest tworzona, należy ustawić odpowiednią wartość początkową dla wszystkich atrybutów składowania typu.

Podczas przechowywania przypisanie własności w konstruktorze, a ich wartości są ustawione bezpośrednio i nie powoduje żadnego majątku obserwatora.

Przechowywanie nieruchomość proces przypisania w konstruktorze:

  • Tworzenie wartości początkowej.

  • W definicji atrybutu określa wartości właściwości domyślnych.

  • Inicjuje instancję i wywołuje metodę init ().


konstruktor

Konstruktor jest wywoływana podczas tworzenia nowej instancji danego typu. Najprostszej postaci jest podobna do metody instancji bez żadnych parametrów, nazwą Init kluczowego.

gramatyka

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

Przykłady

Poniższa struktura określa init konstruktora bez argumentów, a wewnątrz długości atrybutu typu magazynu i wszerz wartości inicjalizacji 6 i 12:

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

Wyjście powyżej wykonywanie programu jest:

矩形面积为 72.0

Domyślne wartości nieruchomości

Możemy ustawić wartości początkowe dla nieruchomości magazynowo-type w konstruktora; Można również ustawić wartość domyślną, gdy deklarację właściwości.

To pozwala na użycie odkurzacza konstruktor domyślny, jaśniejsze, a może automatycznie wnioskować przez atrybut typu wartości domyślne.

Poniższy przykład chcemy, aby ustawić wartość domyślną, gdy deklaracja nieruchomości:

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

Wyjście powyżej wykonywanie programu jest:

矩形面积为 72

parametry konfiguracyjne

Można zdefiniować konstruktor dostarczył init () parametr konstruktora, co następuje:

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

Wyjście powyżej wykonywanie programu jest:

面积为: 72.0
面积为: 432.0

Wewnętrzne i zewnętrzne nazwa parametru

Funkcje i metody o takich samych parametrach, parametry strukturalne są też nazwa parametru w konstruktorze do użytku wewnętrznego i zewnętrznego nazw parametrów wykorzystywanych podczas wywoływania konstruktora.

Jednak konfiguracja nie jest tak jak poprzednio jest rozpoznawalne nazwy w nawiasach, jak funkcje i metody. Więc wywołać konstruktor, konstruktor jest określana głównie przez zadzwonić do nazwy parametrów konstruktora i typów.

Jeśli nie dostarczają argumentów podczas definiowania nazwę zewnętrznego konstruktora, Swift automatycznie wygeneruje nazwę z tą samą nazwą zewnętrznego wewnętrznego każdego parametru konstruktora.

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

Wyjście powyżej wykonywanie programu jest:

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

Brak zewnętrznego nazwa parametru

Jeśli nie chcesz podać imię i nazwisko zewnętrznego dla parametru konstruktora, można użyć znaku podkreślenia _ opisać swoją nazwę zewnętrznego wyświetlacza.

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

Wyjście powyżej wykonywanie programu jest:

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

Opcjonalne atrybuty Typ

Jeśli niestandardowy typ zawiera logiczny argument, aby umożliwić przechowywanie pustych atrybutów typu, trzeba go zdefiniować jako opcjonalne typu opcjonalnego typu (opcjonalnie typu atrybutu).

Podczas przechowywania deklaracji nieruchomość nie jest obowiązkowe, to zostanie on automatycznie inicjowany pustym zera.

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

Wyjście powyżej wykonywanie programu jest:

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

Modyfikacja procesu budowlanego Stała Własności

Tuż przed końcem procesu budowlanego może ustalić wartość stałą, można zmienić wartość stałej atrybutów w dowolnym momencie w procesie budowlanym.

Dla instancji klasy, jego stałym atrybutem może być zdefiniowana tylko w swojej klasie modyfikacji procesu budowy; nie może być zmieniony w podklasie.

Pomimo właściwość length jest to stała, wciąż możemy ustawić jego wartość w konstruktorze swojej klasie:

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

Wyjście powyżej wykonywanie programu jest:

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

Domyślny konstruktor

Domyślny konstruktor będzie po prostu stworzyć wszystkie wartości właściwości są ustawione na wystąpienie domyślne:

Poniższe przykłady, wszystkie właściwości ShoppingListItem klasa ma wartość domyślną, a to nie jest ojcem klasy podstawowej, zostanie ona automatycznie uzyskać można ustawić wartości domyślne dla wszystkich właściwości domyślnego konstruktora

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


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

Wyjście powyżej wykonywanie programu jest:

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

Każdy element struktury konstruktora

Jeśli struktura wszystkich właściwości pamięci masowej typu podać wartości domyślne i nie zapewniają własnej niestandardowy budowniczy, zostaną one automatycznie każdemu członkowi konstruktora.

Kiedy zadzwonić do każdego członka konstruktora, wykonując tradycyjne wartości i członkowie tego samego atrybutu name nazwy parametru, aby zakończyć wstępne przypisanie jej właściwościami.

Poniższy przykład definiuje strukturę Prostokąt, który zawiera dwa atrybuty długość i szerokość. Swift mogą być przydzielane według początkowej 100,0 tych dwóch właściwości, 200,0 automatycznie wyprowadzić ich typ dwukrotnie.

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

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

Ponieważ właściwości dwu-magazynowe mają wartości domyślne, konstrukcje prostokątne automatycznie członkiem każdego pliku init konstruktora (szerokość: wysokość :). Można go używać do tworzenia nowej instancji Rectangle.

Wyjście powyżej wykonywanie programu jest:

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

Wartość agenta typu Konstruktor

Konstruktor przez wywołanie innych konstruktorów, aby zakończyć część instancji procesu budowlanego. Proces ten nazywany jest środek strukturalny, może zmniejszyć powielania kodu między wieloma konstruktorów.

Poniższe przykłady, Rect struktura nazywana procesem budowlanym oraz Punkt Powierzchnia:

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

Wyjście powyżej wykonywanie programu jest:

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) 

Zasady Konstruktor proxy

Typ wartości Klasa Rodzaj
To nie obsługuje dziedziczenia, więc proces jest stosunkowo prosty środek strukturalny, jak inne czynniki mogą tylko konstruktora, aby zapewnić sobie. Można użyć odniesienia self.init innego konstruktora należącej do tego samego rodzaju wartości niestandardowego konstruktora. To może dziedziczyć z innych klas, co oznacza, że ​​klasa ma obowiązek zapewnić wszystkich swoich dziedzicznych właściwości, gdy struktura składowania typu może być właściwie zainicjowana.

Dziedziczenie i budowa proces klasie

Swift oferuje dwa rodzaje konstruktora klasy, aby zapewnić, że wszystkie przypadki właściwości klasy przechowywania można uzyskać w początkowych wartości, które są określone konstruktora i konstruktora ogólnospożywczy.

Określa konstruktora konstruktor Wygoda
Głównym konstruktorem klasy Klasa stosunkowo niewielkie, wspomagana Konstruktor
Cały majątek jest inicjowany klasy ofiarował i wywołać konstruktor klasy nadrzędnej na podstawie łańcucha nadrzędnego celu osiągnięcia inicjalizacji klasy nadrzędnej. Można zdefiniować konstruktor wygodę zadzwonić do tej samej klasy, jak określono w konstruktorze i dostarcza wartości domyślnych parametrów. Można również zdefiniować konstruktor wygody utworzyć wystąpienie określonego celu lub szczególnych nakładów.
Każda klasa musi mieć co najmniej określoną konstruktora Tylko wtedy, gdy to konieczne, aby ułatwić konstruktora klasy
Init(parameters) {
    statements
}
convenience init(parameters) {
      statements
}

Określa konstruktora instancji

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

Wyjście powyżej wykonywanie programu jest:

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

Przykłady konstruktora wygody

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

Wyjście powyżej wykonywanie programu jest:

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

Dziedziczenie i konstruktora przeciążenie

Swift podklasa nie dziedziczy domyślnego konstruktora klasy nadrzędnej.

Konstruktor klasy dominującej jest dziedziczona tylko w przypadku oznaczania i bezpieczeństwa.

Kiedy zastąpić określonej klasy nadrzędnej konstruktora, trzeba napisać modyfikator obejścia.

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

Wyjście powyżej wykonywanie programu jest:

矩形: 4 边
五角型: 5 边

Określa przykłady konstruktor i wygody konstruktorzy

Poniższy przykład zademonstruje działanie określone w konstruktorze konstruktorów i ułatwiają automatyczne konstruktora dziedziczenia.

Zawiera on dwie klasy zdefiniowane MainClass, podklasy klasy hierarchii i pokazują, jak ich interakcji konstruktorów.

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

Wyjście powyżej wykonywanie programu jest:

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

Konstruktor klasy może zawieść

Jeśli klasa, obiekt, struktura lub typ wyliczeniowy, możliwe jest, aby zorganizować się w nie proces, brak zdefiniowania konstruktora.

Zmienna Zainicjowanie nie powiodło się Możliwe przyczyny to:

  • Przychodzące Nieprawidłowa wartość parametru.

  • Brakuje kilku zasobów zewnętrznych wymagany.

  • To nie spełniają określone warunki.

Aby prawidłowo obsługiwać przypadek tego procesu konfiguracji może zawieść.

Można w definicji typu klasy lub enum struktury, dodać jedną lub więcej powiodło konstruktora. Składnia jest pod znakiem zapytania po słowie kluczowym startowych Jiatian (init,?).

Przykłady

W poniższym przykładzie, określenie struktury zwanej zwierzę, które nazwał gatunek, typ String stałych atrybutów.

Tymczasem struktura określa również z typem String gatunków parametrów może zawieść konstruktora. Konstruktor może zawieść, służy do sprawdzania, czy argument przekazany do pustego napisu, pusty ciąg, konstruktor może zawieść, brak na budowę obiektu, w przeciwnym razie sukcesu.

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

Wyjście powyżej wykonywanie programu jest:

动物初始化为长颈鹿

Numeracja konstruktor typu może zabraknąć

Można się z jednego lub większej liczby parametrów mogą być skonfigurowane przez konstruktora nie udało się uzyskać typu wyliczeniowego określonych członków wyliczenia.

Przykłady

W poniższym przykładzie, definicja typu wyliczenia nazwie TemperatureUnit. Która zawiera trzy możliwe członek enum (Kelvina, Celsjusza i Fahrenheita) i awaria może być wykorzystywane w celu znalezienia wartości Konstruktor znak odpowiadający członkowie wyliczenia:

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

Wyjście powyżej wykonywanie programu jest:

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

Konstruktor klasy może zawieść

Typy wartości (takie jak struktury lub typu wyliczeniowego) może zakończyć się niepowodzeniem konstruktora, kiedy i gdzie do uruchomienia budowy nie bez ograniczenia tego problemu.

Jednak konstruktor klasy mogą zawieść i agent może wywołać tylko konstruktor wśród wszystkich klas wystąpił we wszystkich właściwości klasy są inicjowane po zachowaniu awarii zapłonu.

Przykłady

Poprzez przykład, definicja klasy zwanej StudRecord ponieważ nieruchomość studname jest stała, więc raz powodzenia konstruktora klasy StudRecord, nieruchomości studname musi mieć wartość niż zero.

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

Wyjście powyżej wykonywanie programu jest:

模块为 失败构造器

Pokrycie konstruktor może zawieść

Podobnie jak w innych konstruktorów, jak, można również zastąpić konstruktor klasy bazowej może zakończyć się niepowodzeniem konstruktora podklasy może zawieść.

Można również zastąpić przez konstruktora klasy bazowej może zakończyć się niepowodzeniem i niepowodzenia nie konstruktora podklasy.

Można używać non-failed konstruktora obejmującą konstruktor może nie, ale z kolei nie działa.

Non-nieudanym konstruktora nigdy nie może zadzwonić do agenta może nie konstruktora.

Przykłady

Poniższy przykład opisuje awarii i bez awarii Konstruktor:

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

Wyjście powyżej wykonywanie programu jest:

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

Może uda konstruktora Init!

Generalnie, dodajemy pod znakiem zapytania po tym, jak kluczowe init (inicjującego?) Może nie uda się zdefiniować konstruktor, ale można też użyć init dodając wykrzyknik po drodze do określenia uszkodzonego konstruktora (startowy!) , Przykłady są następujące:

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

Wyjście powyżej wykonywanie programu jest:

指定了学生名
学生名为空