您的位置:首页 > 移动开发 > Swift

swift2.0 学习笔记Eleven

2016-05-31 18:22 288 查看
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{

        //执行析构过程

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

        

        

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: