源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Swift编程中的初始化与反初始化完全讲解

  • 时间:2022-09-09 15:34 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Swift编程中的初始化与反初始化完全讲解
[b]初始化 [/b]类,结构和枚举当 Swift 声明后准备初始化类实例。初始值被初始化为存储属性,并且新的实例的值也被进一步进行初始化。创建初始化函数的关键字是通过 init() 方法。Swift 初始化不同于 Objective-C,它不返回任何值。其作用是检查新创建的实例的其处理前初始化。Swift 还提供了“反初始化”过程中执行的内存管理操作当实例被释放。 对于存储的属性初始化器的作用 存储的属性处理实例之前初始化类和结构的实例。 存储属性使用初始分配和初始化值,从而消除了需要调用属性观察者。 初始化用于存储属性: [b]创建初始值[/b] 要在属性定义中指定默认属性值 为特定的数据类型,初始化实例 init()方法被使用,init()函数没有传递参数。 语法
[u]复制代码[/u] 代码如下:
init() {     //New Instance initialization goes here }
示例
[u]复制代码[/u] 代码如下:
struct rectangle {     var length: Double     var breadth: Double     init() {         length = 6         breadth = 12     } } var area = rectangle() println("area of rectangle is \(area.length*area.breadth)")
当我们使用 playground 运行上面的程序,得到以下结果。
area of rectangle is 72.0
这里结构 'rectangle' 使用成员长宽高为 “double” 的数据类型进行初始化。init()方法被用于为新创建的成员的长度和初始化double 类型的数值。 计算长方形的面积,并通过调用矩形函数返回。 [b]通过默认设置属性值 [/b]Swift 语言提供 init()函数来初始化存储的属性值。此外,用户必须规定默认在声明类或结构的成员初始化属性值。当属性的值在整个程序中时一样时,我们可以在声明部分单独声明它,而不是在 init()中初始化。默认情况下,用户设置属性值时能够继承被定义为类或结构。
[u]复制代码[/u] 代码如下:
struct rectangle {     var length = 6     var breadth = 12 } var area = rectangle() println("area of rectangle is \(area.length*area.breadth)")
当我们使用 playground 运行上面的程序,得到以下结果。
area of rectangle is 72.0
在这里,代替声明长和宽在 init()中,在声明本身时就初始化值了。 [b]参数初始化 [/b]在 Swfit 语言用户提供以初始化参数初始化,使用定义作为 init()的一部分。
[u]复制代码[/u] 代码如下:
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) println("area is: \(ar.area)") let are = Rectangle(fromLeng: 36, fromBread: 12) println("area is: \(are.area)")
当我们使用 playground 运行上面的程序,得到以下结果。
area is: 72.0
area is: 432.0
[b]局部及外部参数 [/b]初始化参数具有类似于的函数和方法参数局部和全局参数名称。局部参数声明用于初始化体,外部参数声明访问用于调用初始化。Swift 函数初始化和方法不同,它们不识别哪些初始化用于该函数调用。 为了克服这个问题,Swift 引入了一个自动外部名称为 init()的每个参数。 这种自动外部名称是等同的每一个初始化参数局部名字之前写入。
[u]复制代码[/u] 代码如下:
struct Days {     let sunday, monday, tuesday: Int     init(sunday: Int, monday: Int, tuesday: Int) {         self.sunday = sunday         self.monday = monday         self.tuesday = tuesday     }         init(daysofaweek: Int) {         sunday = daysofaweek         monday = daysofaweek         tuesday = daysofaweek     } } 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
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
[b]不带外部名称参数 [/b]当外部名称不需要一个初始化下划线“_”,这是用来覆盖默认行为。
[u]复制代码[/u] 代码如下:
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) 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
area is: 180.0
area is: 370.0
area is: 110.0

[b]可选属性类型 [/b]当一些实例存储的属性不返回任何值该属性使用 “optional” 类型,表示“没有值”则返回特定类型的声明。当存储的属性被声明为“optional”,它会自动初始化值是'nil' 在其初始化过程中。
[u]复制代码[/u] 代码如下:
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) 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
[b]修改常量属性在初始化时 [/b]初始化还允许用户修改的常量属性的值。在初始化期间,类属性允许它的类的实例被超类修改,而不是由子类进行修改。考虑在之前的程序“长度”的例子,被声明为主类 “变量”。下面的程序变量 'length' 修改为'常量'变量。
[u]复制代码[/u] 代码如下:
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) 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
[b]默认初始化器 [/b]默认初始化提供给基类或结构的所有声明属性的新实例默认值。
[u]复制代码[/u] 代码如下:
class defaultexample {     var studname: String?     var stmark = 98     var pass = true } var result = defaultexample() println("result is: \(result.studname)") println("result is: \(result.stmark)") println("result is: \(result.pass)")
当我们使用 playground 运行上面的程序,得到以下结果。
result is: nil
result is: 98
result is: true
上述程序中定义了类的名字为 “defaultexample'。三个成员函数默认初始化为“studname?”存储值为 'nil' , “stmark”为98和“pass”的布尔值 “true”。 同样,在类中的成员的值可以处理的类成员类型前初始化为默认值。 [b]按成员初始化器结构类型 [/b]当不提供由用户自定义的初始化,在Swift 结构类型将自动接收“成员逐一初始化”。它的主要功能是初始化新的结构实例逐一初始化的默认成员,然后在新的实例属性逐一通过名字传递给成员初始化。
[u]复制代码[/u] 代码如下:
struct Rectangle {     var length = 100.0, breadth = 200.0 } let area = Rectangle(length: 24.0, breadth: 32.0) println("Area of rectangle is: \(area.length)") println("Area of rectangle is: \(area.breadth)")
当我们使用 playground 运行上面的程序,得到以下结果。
Area of rectangle is: 24.0
Area of rectangle is: 32.0
结构由默认初始化为“length”为“100.0”和“breadth”为“200.0”,初始化期间为它们的成员函数。但长度和宽度的变量值在处理过程中覆盖为24.0和32.0。 [b]初始化委托值类型 [/b]初始委托定义调用其它初始化函数初始化。它的主要功能是充当可重用性,以避免在多个初始化代码重复。
[u]复制代码[/u] 代码如下:
struct Stmark {     var mark1 = 0.0, mark2 = 0.0 } struct stdb {     var m1 = 0.0, m2 = 0.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)")
当我们使用 playground 运行上面的程序,得到以下结果。
(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)
[b]初始化函数委派规则 [/b] [img]http://files.jb51.net/file_images/article/201511/2015115152417601.png?2015105152430[/img] [b]类继承和初始化 [/b]类类型有两种初始化函数,以检查是否定义存储属性接收初始值,即指定初始化和方便初始化函数。 指定初始化和便捷初始化器 [img]http://files.jb51.net/file_images/article/201511/2015115152440836.png?2015105152449[/img] [b]程序指定初始化 [/b]
[u]复制代码[/u] 代码如下:
class mainClass {     var no1 : Int // local storage     init(no1 : Int) {         self.no1 = no1 // initialization     } } class subClass : mainClass {     var no2 : Int // new subclass storage     init(no1 : Int, no2 : Int) {         self.no2 = no2 // initialization         super.init(no1:no1) // redirect to superclass     } } 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
res is: 10
res is: 10
res is: 20
[b]程序便捷的初始化 [/b]
[u]复制代码[/u] 代码如下:
class mainClass {     var no1 : Int // local storage     init(no1 : Int) {         self.no1 = no1 // initialization     } } 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)")
当我们使用 playground 运行上面的程序,得到以下结果。
res is: 20
res is: 30
res is: 50
[b]初始化继承和重写 [/b]Swift 默认不允许其子类继承其超类初始化函数为成员类型。继承适用于超类初始化只能在一定程度上,这将在自动初始化程序继承进行讨论。 当用户需要具有在超类,子类中定义的初始化器,初始化函数必须由用户作为自定义实现来定义。 当重写,必须在子类到超类的使用 “override”关键字来声明。
[u]复制代码[/u] 代码如下:
class sides {     var corners = 4     var description: String {         return "\(corners) sides"     } } let rectangle = sides() println("Rectangle: \(rectangle.description)") class pentagon: sides {     override init() {         super.init()         corners = 5     } } let bicycle = pentagon() println("Pentagon: \(bicycle.description)")
当我们使用 playground 运行上面的程序,得到以下结果。
Rectangle: 4 sides
Pentagon: 5 sides
[b]指定和便捷初始化在动作中 [/b]
[u]复制代码[/u] 代码如下:
class Planet {     var name: String         init(name: String) {         self.name = name     }         convenience init() {         self.init(name: "[No Planets]")     } } let plName = Planet(name: "Mercury") println("Planet name is: \(plName.name)") 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)     } }
当我们使用 playground 运行上面的程序,得到以下结果。
Planet name is: Mercury
No Planets like that: [No Planets]
[b]Failable初始化器 [/b]用户必须被通知当在定义一个类,结构或枚举值的任何初始化失败时。变量初始化有时会成为一种失败,由于: [list] [*]无效的参数值[/*] [*]缺少所需的外部来源[/*] [*]有条件阻止初始化成功[/*] [/list] 若要捕获抛出的初始化方法例外,swift 处理产生一种灵活初始化称为“failable 初始化”通知,是留给被忽视在初始化结构,类或枚举成员。关键字捕获 failable 初始值设定 “init?”。此外,failable 和 非failable 初始化函数不能使用相同的参数类型和名称来定义。
[u]复制代码[/u] 代码如下:
struct studrecord {     let stname: String         init?(stname: String) {         if stname.isEmpty {return nil }         self.stname = stname     } } 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") }
当我们使用 playground 运行上面的程序,得到以下结果。
Student name is specified
Student name is left blank
[b]Failable初始值设定为枚举 [/b]Swift 语言提供了灵活性,可以使用 Failable 初始化函数通知用户,从初始化留下来枚举成员值。
[u]复制代码[/u] 代码如下:
enum functions {     case a, b, c, d     init?(funct: String) {         switch funct {         case "one":             self = .a         case "two":             self = .b         case "three":             self = .c         case "four":             self = .d         default:             return nil         }     } } 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") }
当我们使用 playground 运行上面的程序,得到以下结果。
With In Block Two
Block Does Not Exist
[b]Failable初始化器类 [/b]当枚举和结构声明 failable 初始化提醒的初始化失败,在实现中的任意情况。然而, failable 初始化在类中提醒后,才存储属性设置初始值。
[u]复制代码[/u] 代码如下:
class studrecord {     let studname: String!     init?(studname: String) {         self.studname = studname         if studname.isEmpty { return nil }     } } if let stname = studrecord(studname: "Failable Initializers") {     println("Module is \(stname.studname)") }
当我们使用 playground 运行上面的程序,得到以下结果。
Module is Failable Initializers
[b]覆盖一个Failable初始化器 [/b]这样初始化用户也有提供子类覆盖超类的failable 初始化。超级类 failable 初始化也可以在子类非 failable 初始化覆盖。 覆盖一个 failable 超类初始化时,nonfailable 子类初始化子类的初始化器不能委派到超类初始化器。 一个nonfailable初始化不能委托给一个failable初始化。 下面给出的程序描述failable和非failable初始化函数。
[u]复制代码[/u] 代码如下:
class Planet {     var name: String         init(name: String) {         self.name = name     }         convenience init() {         self.init(name: "[No Planets]")     } } let plName = Planet(name: "Mercury") println("Planet name is: \(plName.name)") 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)     } }
当我们使用 playground 运行上面的程序,得到以下结果。
Planet name is: Mercury
No Planets like that: [No Planets] 
[b]init! Failable初始化器 [/b]Swift 提供 “init?”定义一个可选实例failable初始化。要定义特定类型的隐式解包可选的 'int! ' 被指定。
[u]复制代码[/u] 代码如下:
struct studrecord {     let stname: String         init!(stname: String) {         if stname.isEmpty {return nil }         self.stname = stname     } } 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") }
当我们使用 playground 运行上面的程序,得到以下结果。
Student name is specified
Student name is left blank
[b]必需的初始化 [/b]声明并初始化每个子类,“required”关键字的需要在init()函数之前定义。
[u]复制代码[/u] 代码如下:
 class classA {     required init() {         var a = 10         println(a)     } } class classB: classA {     required init() {         var b = 30         println(b)     } } let res = classA() let print = classB()
当我们使用 playground 运行上面的程序,得到以下结果。
10
30
10

[b]反初始化 [/b]一个类实例需要被解除分配之前,“deinitializer”被调用来释放内存空间。关键字 “deinit' 被用于释放由系统资源占用的存储空间。反初始化仅适用于类类型。 反初始化并释放内存空间 Swift 当不再需要它们时自动取消分配实例,以释放资源。Swift 通过自动引用计数(ARC)处理实例的内存管理,如自动引用计数描述。通常情况下无需进行手动清理,实例会自动被释放。但是,当正在使用自己的资源,可能需要自己进行一些额外的清理。例如,如果创建一个自定义类来打开一个文件,写一些数据,可能需要关闭该文件在类实例释放之前。
[u]复制代码[/u] 代码如下:
var counter = 0;  // for reference counting class baseclass {     init() {         counter++;     }     deinit {         counter--;     } } var print: baseclass? = baseclass() println(counter) print = nil println(counter)
当我们使用 playground 运行上面的程序,得到以下结果。
1
0
当 print = nil 语句省略计数器的值保持不变,因为它没有反初始化。
[u]复制代码[/u] 代码如下:
var counter = 0;  // for reference counting class baseclass {     init() {         counter++;     }         deinit {         counter--;     } } var print: baseclass? = baseclass() println(counter) println(counter)
当我们使用 playground 运行上面的程序,得到以下结果。
1
1
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部