MyException - 我的异常网
当前位置:我的异常网» 编程 » 苹果新的编程语言 Swift 语言进阶(十一)--范例

苹果新的编程语言 Swift 语言进阶(十一)--范例的初始化与类的析构

www.MyException.Cn  网友分享于:2014-06-19  浏览:3次
苹果新的编程语言 Swift 语言进阶(十一)--实例的初始化与类的析构

   一 、实例的初始化  

         实例的初始化是准备一个类、结构或枚举的实例以便使用的过程。初始化包括设置一个实例的每一个存储属性为一个初始值,以及执行任何其它新的实例能够使用之前需要的设置或初始化。

         一个类、结构或枚举能定义一个初始化方法来设置它的特性,用来确保它的实例的所有属性都有有效的初始值。

         通过调用类、结构或枚举提供的初始化方法来执行实例的初始化过程。

         类的实例也能实现一个析构,用来在类的实例释放之前执行任何特定的清除过程来释放分配的专有资源。

      1 、 初始化方法的定义

         初始化方法定义与实例方法的定义形式类似,可以包含参数,也可以不包含参数。包含参数时也可以为参数指定本地和外部参数名字。初始化方法的名字固定使用init,且不返回值。

         最简单的初始化方法是不带参数的init方法。

struct Fahrenheit {

   var temperature:Double

   init() {

       temperature =32.0

    }

}

var f =Fahrenheit()

        以上定义了一个名字为Fahrenheit的结构,包含一个初始化方法init,用来在该结构实例化时为它唯一的存储属性temperature分配一个初始值32.0

                 除了在初始化方法中为实例的属性设置初始值外,还能在属性定义时为其提供一个默认值。

                在属性定义时为其提供默认值是更好的初始化属性的方法,一方面语法更加简单,另一方面还可以根据提供的默认值的类型推断属性的类型,而且还可以更好的利用默认初始化和初始化继承的特点。

          下面同样的结构定义,比上面的结构定义语法更简单。

struct Fahrenheit {

   var temperature =32.0

}

           你能使用输入参数和可选的属性类型来定义一个或多个定制的初始化方法,多个定制的初始化方法根据每个初始化方法提供的参数的名称和类型加以区分和被调用。

           如下例子展示了如何使用参数为一个结构定义不同的初始化方法,以及实例化时如何根据初始化方法提供的参数的不同名字来调用相应的初始化方法。

struct Celsius {

   var temperatureInCelsius:Double =0.0

   init(fromFahrenheitfahrenheit:Double) {

       temperatureInCelsius = (fahrenheit -32.0) /1.8

    }

   init(fromKelvinkelvin:Double) {

       temperatureInCelsius =kelvin -273.15

    }

}

let boilingPointOfWater =Celsius(fromFahrenheit:212.0)

// boilingPointOfWater.temperatureInCelsius is 100.0

let freezingPointOfWater =Celsius(fromKelvin:273.15)

        由于初始化方法的参数名字和类型扮演的重要角色,因此如果你在一个初始化方法的定义中没有提供一个外部名字,则Swift会自动为它的每一个参数提供一个自动分配的名字,由Swift自动产生的外部参数名字与本地参数名字相同。

        与实例方法相同,当然如果你不想为初始化方法的参数提供外部参数名字,可以使用’_’作为参数的外部名字。

        常量属性的值能够在初始化期间被修改,但对于类的实例的常量属性,仅能在引入该属性的类的初始化方法中修改,而不能被其子类修改。

  2、 默认初始化方法

      如果一个结构或基类没有提供定制的初始化方法,且其所有的属性都提供有默认值,则Swift能够为其提供一个默认的初始化方法,默认的初始化方法设置新创建的实例的所有属性的值为它们的默认值。如下例子所示:

class ShoppingListItem {

   var name:String?

   var quantity =1

   var purchased =false

}

var item =ShoppingListItem()

     由于类ShoppingListItem的所有的三个属性都提供有默认值,且ShoppingListItem是一个基类,也没有为其提供定制的初始化方法,因此Swift为其提供了一个默认初始化方法,默认初始化方法不带参数。

  3、 结构类型的成员逐一初始化方法(memberwise Initializers)

       如果一个结构的所有的存储属性都提供有默认值,且没有定义任何自己的定制初始化方法,则除了可以使用Swift为其提供的默认初始化方法外,也自动接收一个成员逐一初始化方法。

       成员逐一初始化方法是初始化新结构实例的成员属性的一种快捷方式,新实例的所有属性的初始值通过名字逐一传送给该初始化方法然后被设置。如下所示:

     struct Size {

     var width =0.0,height =0.0

     }

let twoByTwo =Size(width:2.0,height:2.0)

          在该例子中,结构Size包含仅有的两个存储属性width和height,并都带有默认值,而其本身也没有提供初始化方法,因此其自动接收一个为init(width:height:)的成员逐一初始化方法。能够使用它来初始化一个新的Size实例,其属性的初始值通过成员逐一初始化方法的参数逐一提供。    

     对于值类型(结构和枚举),你能在自己定义的初始化方法内部使用self.init调用相同类型的其它初始化方法。

  4、 类的初始化 

       由于类涉及继承,因此一个类的初始化过程比较复杂,需要在初始化过程完成对类的所有存储属性(包括从它的超类琏继承的任意属性)的初始化。Swift为了确保正确完成一个类的初始化,定义了两类类的初始化方法:指派初始化方法和便利初始化方法。

   4.1、 类的指派初始化方法和便利初始化方法

       类的指派初始化方法是一个类的主要初始化方法。一个类的指派初始化方法初始化该类本身引入的所有的属性,然后向上调用其直接超类的初始化方法来继续超类琏的初始化过程。一个类必须有至少一个指派初始化方法,通常一个类仅有一个指派初始化方法。

       类的便利初始化方法是类的次要初始化方法,你能为类定义一个便利初始化方法来调用相同类的其它初始化方法。一个类可以不必提供便利初始化方法。

       便利初始化方法作为一种便利的初始化方法,主要用来方便创建某些特定的实例或者特定输入值类型的类的实例,因此在便利初始化方法中调用指派初始化方法时,对于指派初始化方法的一些参数被设置为默认值。              

       类的指派初始化方法和便利初始化方法之间的调用必须遵守如下规则:

       1)指派初始化方法必须调用它的直接超类的指派初始化方法;

       2)便利初始化方法必须调用相同类的另外的可以使用的初始化方法;

       3) 便利初始化方法最后必须调用一个指派初始化方法。

       类的指派初始化方法语法与值类型的简单初始化方法相同:

   init(parameters) {

    statements

  }

       便利初始化方法的语法除了使用convenience关键字来标示外,语法与指派初始化方法相同。

   convenience init(parameters) {

    statements

  }

   4.2、 类的两阶段初始化

        在Swift中类的初始化分成两个阶段完成,在第一个阶段,每一个存储属性被引入它的类的初始化方法分配一个初始值。一旦每个存储属性的初始状态确定,开始第二个初始化阶段:在新的实例能够使用之前,进一步定制它的存储属性。

        为了正确完成一个类的两阶段初始化过程,Swift进行如下安全检查:

        1) 指派初始化方法必须在调用它的直接超类的初始化方法之前确保由它的类引入的所有的属性被初始化。

        2) 指派初始化方法在为一个继承的属性分配一个值之前必须向上调用它的直接超类的初始化方法;

        3) 便利初始化方法必须在为任何属性分配值之前调用其它的初始化方法;

        4) 一个初始化方法在第一个阶段完成前不能调用其它任何实例方法,读任何实例属性的值或者引用self,这是因为这时实例还处于内存不确定状态。

   4.3、 初始化方法的继承和重写

        与Objective-C语言不同,Swift 中子类默认不继承它的超类的初始化方法。但允许在子类中重写超类的初始化方法。与方法、属性、下标不同,初始化方法的重写不需要写一个override标识。

   4.4、 自动初始化继承

       在一些条件下,超类的初始化方法也能被它的子类自动继承。

       规则1:如果一个子类没有定义任何指派初始化方法,则自动继承它的超类的所有指派初始化方法。即对于指派初始化方法继承而言,没有则继承。

       规则2:如果一个子类提供了其超类的所有指派初始化方法的实现,可以是通过规则1继承来的,也可以是提供自己特定的实现,那么它自动继承其超类的所有便利初始化方法。即对于便利初始化方法继承而言如果已实现超类的所有指派初始化方法,则自动继承所有便利初始化方法。

  5、 使用闭合或功能为属性设置默认值

              你能使用一个闭合或全局功能来为一个存储属性提供特定的默认值。在该属性所属类型的新的实例被初始化时,为一个属性提供默认值的闭合或全局功能被调用,且返回一个值作为该属性的默认值。如下所示:

   class SomeClass {

     let someProperty:SomeType = {

   

       return someValue

        }()

  }

              该例使用一个闭合为someProperty属性提供默认值,该闭合以一个圆括号结束,说明该闭合能够被执行。

      需要注意:在使用一个闭合为一个属性分配默认值时,因为在闭合执行时,该实例还没有初始化完成,因此在闭合内部不能存取实例的其它任何属性值,即使那些属性带有默认值,也不能使用隐含的self属性,也不能调用任何实例的方法。

二、析构

        在一个实例不再需要时,Swift会自动释放它。Swift使用automatic reference counting (ARC)来实现一个实例的内存管理。因此当实例释放时,用户不需要手工清除它所使用的系统资源。可是当你的实例包含和使用了自己分配的资源时,你可能需要执行一些额外的清除工作。例如创建一个打开一个文件的类,就可能需要在类的实例释放前关闭该文件。

          每个类能够定义至少一个析构,析构语法如下:

deinit {

   // perform the deinitialization

}

           一个实例的析构在实例释放之前自动被调用。超类的析构被子类继承,超类的析构能够在子类的析构实现的最后被自动调用。

           超类的析构总是被调用,即使一个没有提供自己的析构的子类。

           在一个实例的析构完成之前该实例还没有被释放,因此在析构内部能够存取实例的所有属性。


                                  版权所有,转载时请清楚注明链接和出处,谢谢!

文章评论

 程序员的样子
程序员的样子
我是如何打败拖延症的
我是如何打败拖延症的
程序员的鄙视链
程序员的鄙视链
Java程序员必看电影
Java程序员必看电影
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员应该关注的一些事儿
程序员应该关注的一些事儿
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员必看的十大电影
程序员必看的十大电影
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
10个调试和排错的小建议
10个调试和排错的小建议
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
如何成为一名黑客
如何成为一名黑客
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
代码女神横空出世
代码女神横空出世
鲜为人知的编程真相
鲜为人知的编程真相
程序员都该阅读的书
程序员都该阅读的书
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
一个程序员的时间管理
一个程序员的时间管理
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
旅行,写作,编程
旅行,写作,编程
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
为什么程序员都是夜猫子
为什么程序员都是夜猫子
漫画:程序员的工作
漫画:程序员的工作
老程序员的下场
老程序员的下场
总结2014中国互联网十大段子
总结2014中国互联网十大段子
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
每天工作4小时的程序员
每天工作4小时的程序员
那些争议最大的编程观点
那些争议最大的编程观点
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
中美印日四国程序员比较
中美印日四国程序员比较
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
编程语言是女人
编程语言是女人
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有