时间:2021-03-28 09:15:32 | 栏目: | 点击:次
初始化
类,结构和枚举当 Swift 声明后准备初始化类实例。初始值被初始化为存储属性,并且新的实例的值也被进一步进行初始化。创建初始化函数的关键字是通过 init() 方法。Swift 初始化不同于 Objective-C,它不返回任何值。其作用是检查新创建的实例的其处理前初始化。Swift 还提供了“反初始化”过程中执行的内存管理操作当实例被释放。
对于存储的属性初始化器的作用
存储的属性处理实例之前初始化类和结构的实例。 存储属性使用初始分配和初始化值,从而消除了需要调用属性观察者。 初始化用于存储属性:
创建初始值
要在属性定义中指定默认属性值
为特定的数据类型,初始化实例 init()方法被使用,init()函数没有传递参数。
语法
area of rectangle is 72.0
这里结构 'rectangle' 使用成员长宽高为 “double” 的数据类型进行初始化。init()方法被用于为新创建的成员的长度和初始化double 类型的数值。 计算长方形的面积,并通过调用矩形函数返回。
通过默认设置属性值
Swift 语言提供 init()函数来初始化存储的属性值。此外,用户必须规定默认在声明类或结构的成员初始化属性值。当属性的值在整个程序中时一样时,我们可以在声明部分单独声明它,而不是在 init()中初始化。默认情况下,用户设置属性值时能够继承被定义为类或结构。
area of rectangle is 72.0
在这里,代替声明长和宽在 init()中,在声明本身时就初始化值了。
参数初始化
在 Swfit 语言用户提供以初始化参数初始化,使用定义作为 init()的一部分。
let ar = Rectangle(fromLength: 6, fromBreadth: 12)
println("area is: \(ar.area)")
let are = Rectangle(fromLeng: 36, fromBread: 12)
println("area is: \(are.area)")
area is: 72.0 area is: 432.0
局部及外部参数
初始化参数具有类似于的函数和方法参数局部和全局参数名称。局部参数声明用于初始化体,外部参数声明访问用于调用初始化。Swift 函数初始化和方法不同,它们不识别哪些初始化用于该函数调用。
为了克服这个问题,Swift 引入了一个自动外部名称为 init()的每个参数。 这种自动外部名称是等同的每一个初始化参数局部名字之前写入。
let week = Days(sunday: 1, monday: 2, tuesday: 3)
println("Days of a Week is: \(week.sunday)")
println("Days of a Week is: \(week.monday)")
println("Days of a Week is: \(week.tuesday)")
let weekdays = Days(daysofaweek: 4)
println("Days of a Week is: \(weekdays.sunday)")
println("Days of a Week is: \(weekdays.monday)")
println("Days of a Week is: \(weekdays.tuesday)")
Days of a Week is: 1 Days of a Week is: 2 Days of a Week is: 3 Days of a Week is: 4 Days of a Week is: 4 Days of a Week is: 4
不带外部名称参数
当外部名称不需要一个初始化下划线“_”,这是用来覆盖默认行为。
let rectarea = Rectangle(180.0)
println("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
println("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
println("area is: \(recarea.length)")
area is: 180.0 area is: 370.0 area is: 110.0
可选属性类型
当一些实例存储的属性不返回任何值该属性使用 “optional” 类型,表示“没有值”则返回特定类型的声明。当存储的属性被声明为“optional”,它会自动初始化值是'nil' 在其初始化过程中。
let rectarea = Rectangle(180.0)
println("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
println("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
println("area is: \(recarea.length)")
area is: Optional(180.0) area is: Optional(370.0) area is: Optional(110.0)
修改常量属性在初始化时
初始化还允许用户修改的常量属性的值。在初始化期间,类属性允许它的类的实例被超类修改,而不是由子类进行修改。考虑在之前的程序“长度”的例子,被声明为主类 “变量”。下面的程序变量 'length' 修改为'常量'变量。
let rectarea = Rectangle(180.0)
println("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
println("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
println("area is: \(recarea.length)")
area is: Optional(180.0) area is: Optional(370.0) area is: Optional(110.0)
默认初始化器
默认初始化提供给基类或结构的所有声明属性的新实例默认值。
println("result is: \(result.studname)")
println("result is: \(result.stmark)")
println("result is: \(result.pass)")
result is: nil result is: 98 result is: true
上述程序中定义了类的名字为 “defaultexample'。三个成员函数默认初始化为“studname?”存储值为 'nil' , “stmark”为98和“pass”的布尔值 “true”。 同样,在类中的成员的值可以处理的类成员类型前初始化为默认值。
按成员初始化器结构类型
当不提供由用户自定义的初始化,在Swift 结构类型将自动接收“成员逐一初始化”。它的主要功能是初始化新的结构实例逐一初始化的默认成员,然后在新的实例属性逐一通过名字传递给成员初始化。
println("Area of rectangle is: \(area.length)")
println("Area of rectangle is: \(area.breadth)")
Area of rectangle is: 24.0 Area of rectangle is: 32.0
结构由默认初始化为“length”为“100.0”和“breadth”为“200.0”,初始化期间为它们的成员函数。但长度和宽度的变量值在处理过程中覆盖为24.0和32.0。
初始化委托值类型
初始委托定义调用其它初始化函数初始化。它的主要功能是充当可重用性,以避免在多个初始化代码重复。
struct block {
var average = stdb()
var result = Stmark()
init() {}
init(average: stdb, result: Stmark) {
self.average = average
self.result = result
}
init(avg: stdb, result: Stmark) {
let tot = avg.m1 - (result.mark1 / 2)
let tot1 = avg.m2 - (result.mark2 / 2)
self.init(average: stdb(m1: tot, m2: tot1), result: result)
}
}
let set1 = block()
println("student result is: \(set1.average.m1, set1.average.m2) \(set1.result.mark1, set1.result.mark2)")
let set2 = block(average: stdb(m1: 2.0, m2: 2.0),
result: Stmark(mark1: 5.0, mark2: 5.0))
println("student result is: \(set2.average.m1, set2.average.m2) \(set2.result.mark1, set2.result.mark2)")
let set3 = block(avg: stdb(m1: 4.0, m2: 4.0),
result: Stmark(mark1: 3.0, mark2: 3.0))
println("student result is: \(set3.average.m1, set3.average.m2) \(set3.result.mark1, set3.result.mark2)")
(0.0,0.0) (0.0,0.0) (2.0,2.0) 5.0,5.0) (2.5,2.5) (3.0,3.0)
初始化函数委派规则

类继承和初始化
类类型有两种初始化函数,以检查是否定义存储属性接收初始值,即指定初始化和方便初始化函数。
指定初始化和便捷初始化器

程序指定初始化
let res = mainClass(no1: 10)
let print = subClass(no1: 10, no2: 20)
println("res is: \(res.no1)")
println("res is: \(print.no1)")
println("res is: \(print.no2)")
res is: 10 res is: 10 res is: 20
程序便捷的初始化
class subClass : mainClass {
var no2 : Int
init(no1 : Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
println("res is: \(res.no1)")
println("res is: \(print.no1)")
println("res is: \(print.no2)")
res is: 20 res is: 30 res is: 50
初始化继承和重写
Swift 默认不允许其子类继承其超类初始化函数为成员类型。继承适用于超类初始化只能在一定程度上,这将在自动初始化程序继承进行讨论。
当用户需要具有在超类,子类中定义的初始化器,初始化函数必须由用户作为自定义实现来定义。 当重写,必须在子类到超类的使用 “override”关键字来声明。
class pentagon: sides {
override init() {
super.init()
corners = 5
}
}
let bicycle = pentagon()
println("Pentagon: \(bicycle.description)")
Rectangle: 4 sides Pentagon: 5 sides
指定和便捷初始化在动作中
let noplName = Planet()
println("No Planets like that: \(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)
}
}
Planet name is: Mercury No Planets like that: [No Planets]
Failable初始化器
用户必须被通知当在定义一个类,结构或枚举值的任何初始化失败时。变量初始化有时会成为一种失败,由于:
若要捕获抛出的初始化方法例外,swift 处理产生一种灵活初始化称为“failable 初始化”通知,是留给被忽视在初始化结构,类或枚举成员。关键字捕获 failable 初始值设定 “init?”。此外,failable 和 非failable 初始化函数不能使用相同的参数类型和名称来定义。
let stmark = studrecord(stname: "Swing")
if let name = stmark {
println("Student name is specified")
}
let blankname = studrecord(stname: "")
if blankname == nil {
println("Student name is left blank")
}
Student name is specified Student name is left blank
Failable初始值设定为枚举
Swift 语言提供了灵活性,可以使用 Failable 初始化函数通知用户,从初始化留下来枚举成员值。
let result = functions(funct: "two")
if result != nil {
println("With In Block Two")
}
let badresult = functions(funct: "five")
if badresult == nil {
println("Block Does Not Exist")
}
With In Block Two Block Does Not Exist
Failable初始化器类
当枚举和结构声明 failable 初始化提醒的初始化失败,在实现中的任意情况。然而, failable 初始化在类中提醒后,才存储属性设置初始值。
Module is Failable Initializers
覆盖一个Failable初始化器
这样初始化用户也有提供子类覆盖超类的failable 初始化。超级类 failable 初始化也可以在子类非 failable 初始化覆盖。
覆盖一个 failable 超类初始化时,nonfailable 子类初始化子类的初始化器不能委派到超类初始化器。
一个nonfailable初始化不能委托给一个failable初始化。
下面给出的程序描述failable和非failable初始化函数。
let noplName = Planet()
println("No Planets like that: \(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)
}
}
Planet name is: Mercury No Planets like that: [No Planets]
init! Failable初始化器
Swift 提供 “init?”定义一个可选实例failable初始化。要定义特定类型的隐式解包可选的 'int! ' 被指定。
let stmark = studrecord(stname: "Swing")
if let name = stmark {
println("Student name is specified")
}
let blankname = studrecord(stname: "")
if blankname == nil {
println("Student name is left blank")
}
Student name is specified Student name is left blank
必需的初始化
声明并初始化每个子类,“required”关键字的需要在init()函数之前定义。
class classB: classA {
required init() {
var b = 30
println(b)
}
}
let res = classA()
let print = classB()
10 30 10
反初始化
一个类实例需要被解除分配之前,“deinitializer”被调用来释放内存空间。关键字 “deinit' 被用于释放由系统资源占用的存储空间。反初始化仅适用于类类型。
反初始化并释放内存空间
Swift 当不再需要它们时自动取消分配实例,以释放资源。Swift 通过自动引用计数(ARC)处理实例的内存管理,如自动引用计数描述。通常情况下无需进行手动清理,实例会自动被释放。但是,当正在使用自己的资源,可能需要自己进行一些额外的清理。例如,如果创建一个自定义类来打开一个文件,写一些数据,可能需要关闭该文件在类实例释放之前。
var print: baseclass? = baseclass()
println(counter)
print = nil
println(counter)
1 0
当 print = nil 语句省略计数器的值保持不变,因为它没有反初始化。
class baseclass {
init() {
counter++;
}
deinit {
counter--;
}
}
var print: baseclass? = baseclass()
println(counter)
println(counter)
1 1