swift2.0 学习笔记Eleven

原创 2016年05月31日 18:22:22



import UIKit


class ViewController: UIViewController {

 

    override func viewDidLoad() {

        super.viewDidLoad()

        //类的可失败构造器

        //值类型(结构体或枚举类型)的可失败构造器,对何时何地触发构造失败这个行为没有任何限制,然而对类而言只能在所有的类属性被初始化后和所有类之间的构造器之间的代理调用发生完后触发失败行为

        class Product{

            let name: String!

            init?(name:String){

                self.name = name

                if name.isEmpty{return nil}

            }

        }

        //因为name属性是一个常量,所以一旦Product类构造成功,name属性肯定有一个非nil的值。

        if let bowTie = Product(name: "DLG"){

            print(bowTie.name)

        }

        //构造失败的传递

        //可失败构造器允许在同一类,结构体和枚举中横向代理其它的可失败构造器。类似的,子类的可失败构造器也能向上代理基类的可失败构造器

        //注意:无论是向上代理还是横向代理,如果你代理的可失败构造器,在构造过程中触发了构造失败行为,整个构造过程都将被立即终止,接下来任何的构造代码都将不会执行。

        

        

        //一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用解析来获取可选值。

        let possibleStr :String? = "An optional string"

        let forceStr:String = possibleStr!//需要惊叹号来获取值

        let assumeStr :String! = "An implicitly unwrapped optional string."

        let implicitStr: String = assumeStr//不需要感叹号

        //你可以把隐式解析可选类型当作一个可以自动解析的可选类型,你要做的只是声明的时候把感叹号放到类型的结尾。

        

        class CartItem: Product{

            var quantity:Int! //隐式解析可选类型

            init?(name: String,quantity:Int) {

                self.quantity = quantity

                super.init(name: name)

                if quantity<1{

                    return nil

                }

                

            }

        }

        if let zeroShirts = CartItem(name: "shirt", quantity: 0)

        {

            print("\(zeroShirts.name)\(zeroShirts.quantity)")

        }else{

            print("Unable to init")

        }//Unable to init

        

        

        if let oneUnname=CartItem(name: "", quantity: 1){

            print("\(oneUnname.name)")

        }else{

            print("unable to init !")

        }//unable to init !

        

        //当一个子类的非可失败构造器重写了一个父类的可失败构造器时,子类的构造器将不能向上代理父类的可失败构造器,一个非可失败的构造器永远也不能代理调用一个可失败的构造器

        //可以用一个非可失败构造器重写一个可失败构造器,但是反过来却行不通

      

        class Document{

            var name:String?

            init(){}

            init?(name:String){//该构造器构建了一个name属性值为非空字符串的Document对象

                if name.isEmpty{return nil}

                self.name=name

            }

        }

        class AutomaticDocument:Document{

            override init(){

                super.init()

                self.name="Untitled"

            }

            override init(name: String) {

                super.init()

                if name.isEmpty{

                    self.name="Unitl"

                }else{

                    self.name=name

                }

            }

        }//AutomaticDocument用一个非可失败构造器init(name:),重写了父类的可失败构造器init?(name:)

        

        class UntitleDoc :Document{

            override init() {

                super.init(name: "Untitled")!

            }

        }

        

        //可失败构造器init

        //通常来说我们通过在init关键字后添加问号的方式来定义一个可失败构造器,但是也可以使用通过在init后面添加感叹号的方式来定义一个可失败构造器(init!)

        //该可失败构造器将会构建一个特定类型的隐式解析可选类型的对象

        

        //必要构造器

        //在类的构造器前添加required修饰符表明所有该类的子类都必须实现该构造器

        class SomeClass{

            required init(){

                //这里添加该必要构造器的实现代码

            }

        }

        class SomeSubClass:SomeClass{

            required init() {

                //在这里添加子类必要构造器的实现代码

                

            }

        }//在子类重写父类的必要构造器时,必须在子类的构造器前也添加required修饰符,这是保证继承链上子类的构造器也是必要构造器。在重写父类的必要构造器时,不需要添加override修饰符

        

        //通过闭包和函数来设置属性的默认值

        //当某个属性所属的新类型实例创建时,对应的闭包或函数会被调用,而它们的返回值会当做默认值赋值给这个属性

        class someClass{

            var aaa :Int{   //只读计算属性

                return 100

            }

            let someProperty: String = {

                //在这个闭包中给someProperty创建一个默认值

                return "1234"

            }()

        }

        //注意:闭包结尾的大括号后面接了一对空的小括号。这是用来告诉swift需要立即执行此闭包。如果忽略了这对括号,相当于是将闭包本身作为值赋值给属性,而不是将闭包的返回值给属性

        //如果使用闭包来初始化属性的值,在闭包执行时。实例的其它部分都还没有初始化。这意味着不能够在闭包里访问其它的属性,即使这个属性有默认值也不允许。

        

        struct checkerboard{

        //不能够在闭包里访问其它的属性

        let boardColors:[Bool]={

               var temporaryBoard = [Bool]()

               var isBlack = false

                for i in 1...10{

                    for j in 1...10{

                        temporaryBoard.append(isBlack)

                        isBlack = !isBlack

                    }

                    isBlack = !isBlack

                }

                return temporaryBoard

            }()

            func squareIsBlackAtRow(row : Int,column : Int)->Bool{

                return boardColors[(row * 10)+column]

            }

        }

        //每当一个新的checkerboard实例创建时,对应的赋值闭包会执行

        let board = checkerboard()

        print(board.squareIsBlackAtRow(0, column: 1))//true

        print(board.squareIsBlackAtRow(9, column: 9))//false

        

        struct Bank{

            static var coinsInBank = 10_000

            static func vendCoins(var numberOfCoinsToVend:Int)->Int{

                numberOfCoinsToVend=min(numberOfCoinsToVend, coinsInBank)

                coinsInBank -= numberOfCoinsToVend

                return numberOfCoinsToVend

            }

            static func receiveCoins(coins:Int){

                coinsInBank += coins

            }

        }

        //Player类描述了游戏中的一个玩家。每一个player在任何时刻都有一定数量的硬币存储在他们的钱包中通过coinsInPurse属性来体现

        class Player{

            var coinsInPurse:Int

            init(coins:Int){

                coinsInPurse=Bank.vendCoins(coins)

            }

            func winCoins(coins :Int){

                coinsInPurse += Bank.vendCoins(coins)

            }

            deinit{

                Bank.receiveCoins(coinsInPurse)

            }

        }

        var playerOne:Player!=Player(coins: 100)

        print("\(playerOne.coinsInPurse) coins!")//100 coins!

        print("\(Bank.coinsInBank)coins left in the bank")//9900coins left in the bank

        playerOne.winCoins(2_000)

        print("won 2000 coins now has\(playerOne.coinsInPurse) coins")//won 2000 coins now has2100 coins

        print("\(Bank.coinsInBank)coins left in the bank")//7900coins left in the bank

        playerOne = nil //玩家离开游戏

        print("\(Bank.coinsInBank)coins left in the bank")//10000coins left in the bank

        

        

    }

    //析构过程原理

    //swift会自动释放不在需要的实例以释放资源。通常你的实例被释放时不需要手动地去清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。

    //在类的定义中,每个类最多只能有一个析构器,并且析构器不带任何参数

    deinit{

        //执行析构过程

        //析构器是在实例释放发生前被自动调用。析构器是不允许被主动调用的,子类继承了父类的析构器,并且在子类析构器实现的最后,父类的析构器会被自动调用。即使子类没有提供自己的析构器,父类的析构器也同样会被调用

        

        

    }

}









版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Swift2.0--文档学习笔记

最近把《The Swift Programming Language 中文版》粗略地看了一遍,并随手留了点笔记,以备忘。 1、闭包,通过闭包对字符串数组进行排序,闭包的函数体部分由关键字in引入 n...

《从零开始学Swift》Swift 2.0学习笔记(Day 38)——构造函数与存储属性初始化

原创文章,欢迎转载。转载请注明:关东升的博客  构造函数的主要作用是初始化实例,其中包括:初始化存储属性和其它的初始化。在Rectangle类或结构体中,如果在构造函数中初始化存储属性width和he...

IOS开发-Swift-基础知识学习笔记

  • 2017年04月25日 11:34
  • 33KB
  • 下载

Swift学习笔记

  • 2014年06月06日 20:47
  • 233KB
  • 下载

Libevent 学习笔记 (1)——Libevent 2.0安装与简单示例

今天主要进行了Libevent的安装,以及利用libevent框架编写一个间隔1s打印 Hello Libevent!信息的程序。首先是安装: 1 下载libevent源码,下载地址http://l...

swift快速学习笔记1

  • 2014年06月07日 08:48
  • 198KB
  • 下载

coco2d-v2.0粒子系统学习笔记

  • 2013年09月11日 10:59
  • 5KB
  • 下载

kinect 2.0 SDK学习笔记(六)--深度图的实时平滑之加权移动平均机制

上一节我们介绍了像素滤波器,下面介绍另一个实时平滑深度图的机制–加权移动平均机制。3.2 加权移动平均机制我们通过观察可以发现,即使kinect采集的是一个静止的场景,在得到的深度图上,同一个像素位置...

opengl es 2.0 学习笔记

  • 2010年07月29日 16:24
  • 381KB
  • 下载

Ext2.0的学习笔记

  • 2008年09月26日 10:37
  • 23KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:swift2.0 学习笔记Eleven
举报原因:
原因补充:

(最多只允许输入30个字)