Swift 构造过程+析构过程(十三)

Swift 构造过程+析构过程(十三),第1张

概述构造过程 (Initialization) 1.存储类型的初始赋值 类和结构在创建实例的时候,必须为所有的存储属性设置值,不能为nil 1.1构造器 构造器在创建某个特定类型的新实例的时候调用,最简形式类似不带参数的方法,以init命名 [objc]  view plain copy struct Fahrenheit {       var temperature: Double       i 构造过程 (Initialization) 1.存储类型的初始赋值 类和结构在创建实例的时候,必须为所有的存储属性设置值,不能为nil

1.1构造器 构造器在创建某个特定类型的新实例的时候调用,最简形式类似不带参数的方法,以init命名
[objc] view plain copy structFahrenheit{ vartemperature:Double init(){ temperature=32.0 } } varf=Fahrenheit() println("Thedefaulttemperatureis\(f.temperature)°Fahrenheit") //prints"Thedefaulttemperatureis32.0°Fahrenheit"
1.2默认属性值 在属性生命的时候直接为其设置默认值
vartemperature=32.0 }
2.定制化构造过程 2.1构造参数 在定义构造器的时候提供构造参数,语法跟函数和方法相同
structCelsius{ temperatureInCelsius:Double=0.0 init(fromFahrenheitfahrenheit:Double){ temperatureInCelsius=(fahrenheit-32.0)/1.8 init(fromKelvinkelvin:Double){ temperatureInCelsius=kelvin-273.15 letboilingPointOfWater=Celsius(fromFahrenheit:212.0) //boilingPointOfWater.temperatureInCelsiusis100.0 letfreezingPointOfWater=Celsius(fromKelvin:273.15) //freezingPointOfWater.temperatureInCelsiusis0.0
2.2内部和外部参数名 构造函数存在一个构造器内部使用的参数名和一个在调用时使用的外部参数名,如果没有提供参数的外部名字,Swift会自动为每个构造器的参数生成一个跟内部参数名相同的外部参数名
structcolor{ letred=0.0,green=0.0,blue=0.0 init(red:Double,green:Double,blue:Double){ self.red=red self.green=green self.blue=blue letmagenta=color(red:1.0,0); background-color:inherit">green:0.0,0); background-color:inherit">blue:1.0) //如果不通过外部参数名传值,编译时无法通过 letveryGreen=color(0.0,1.0,0.0) //thisreportsacompile-timeerror-externalnamesarerequired
2.3可选属性类型 如果定义的类型包含一个可以为空的存储型属性,需要将其定义为可选类型 (optional type), 则自动初始化为nil,表示这个属性是故意初始化设置为空的
classSurveyQuestion{ text:String varresponse:String? init(text:String){ self.text=text funcask(){ println(text) letcheeseQuestion=SurveyQuestion(text:"Doyoulikecheese?") cheeseQuestion.ask() //prints"Doyoulikecheese?" cheeseQuestion.response="Yes,IDolikecheese."
2.4构造过程中常量的修改 只要在构造过程结束后能确定常量的值,就可以在构造过程之中随意修改常量的值
//尽管text属性是常量,但在构造过程之中还是可以修改的,构造过程结束时候不能再修改了 classSurveyQuestion{ lettext:String response:String? init(text:String){ self.text=text funcask(){ println(text) letbeetsQuestion=SurveyQuestion(text:"Howaboutbeets?") beetsQuestion.ask() //prints"Howaboutbeets?" beetsQuestion.response="Ialsolikebeets.(Butnotwithcheese.)"
3.默认构造器 Swift为素有属性已提供默认值的但自身没有构造器的结构体或基类提供一个默认的构造器,构造器创建一个将所有属性值都设置为默认值的实例
classShopPingListItem{ name:String? varquantity=1 varpurchased=false varitem=ShopPingListItem() structSize{ varwIDth=0.0,height=0.0 lettwoByTwo=Size(wIDth:2.0,0); background-color:inherit">height:2.0)
4.值类型的构造器代理 构造器通过调用其他构造器来完成实例的部分构造,提高代码利用率,称为构造器的代理
structPoint{ varx=0.0,y=0.0 structRect{ varorigin=Point() varsize=Size() init(){} init(origin:Point,0); background-color:inherit">size:Size){ self.origin=origin self.size=size init(center:Point,248)"> letoriginX=center.x-(size.wIDth/2) letoriginY=center.y-(size.height/2) self.init(origin:Point(x:originX,0); background-color:inherit">y:originY),0); background-color:inherit">size:size) letbasicRect=Rect() //basicRect'soriginis(0.0,0.0)anditssizeis(0.0,0.0) letoriginRect=Rect(origin:Point(x:2.0,0); background-color:inherit">y:2.0), size:Size(wIDth:5.0,0); background-color:inherit">height:5.0)) //originRect'soriginis(2.0,2.0)anditssizeis(5.0,5.0) 5.类的继承和构造过程 类里所有的存储类型属性包括继承父类的属性都需要在构造过程中设置初始值,Swift提供两种类型的类构造器来确保所有类实例中的存储属性都能获得初始值

5.1指定构造器和便利构造器 指定构造器是类中最主要的构造器,将初始化类中所提供的所有属性,每个类至少需要一个指定构造器,便利构造器是辅助型的构造器,可调用同一类中的指定构造器,并为其参数提供默认值

5.2构造器链 Swift采用三条规则来限制构造器之间的代理调用
a.指定构造器必须调用其直接父类的指定构造器
b.便利构造器必须调用同一类中定义的其他构造器
c.便利构造器最终必须调用一个指定构造器结束
(指定构造器总是向上代理,便利构造器总是横向代理)

5.3构造器的继承和重载 Swift中的子类默认不会继承父类的构造器,防止父类的简单构造被子类继承,并错误的创建子类的实例,如果希望子类能继承父类相同的构造器,需要定制子类的构造器

5.4指定构造器和便利构造器的语法 init(parameters){ statements //便利构造器前置convenIEnce关键字 convenIEnceinit(parameters){ classFood{ name:String init(name:String){ self.name=name convenIEnceinit(){ self.init(name:"[Unnamed]") letnamedmeat=Food(name:"Bacon") //namedmeat'snameis"Bacon" letmysterymeat=Food() //mysterymeat'snameis"[Unnamed]" classRecipeIngredIEnt:Food{ quantity:Int init(name:String,0); background-color:inherit">quantity:Int){ self.quantity=quantity super.init(name:name) convenIEnceinit(name:String){ self.init(name:name,0); background-color:inherit">quantity:1) letoneMysteryItem=RecipeIngredIEnt() letoneBacon=RecipeIngredIEnt(name:"Bacon") letsixEggs=RecipeIngredIEnt(name:"Eggs",0); background-color:inherit">quantity:6) ShopPingListItem:RecipeIngredIEnt{ varpurchased=false description:String{ varoutput="\(quantity)x\(name.lowercaseString)" output+=purchased?"✔":"✘" returnoutput varbreakfastList=[ ShopPingListItem(), ShopPingListItem(name:"Bacon"), ShopPingListItem(name:"Eggs",0); background-color:inherit">quantity:6),108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> ] breakfastList[0].name="Orangejuice" breakfastList[0].purchased=true foriteminbreakfastList{ println(item.description) //1xorangejuice✔ //1xbacon✘ //6xeggs✘
6.通过闭包和函数来设置属性的默认值 属性可以使用闭包或全局函数来提供默认值,当创建新实例时,对应的闭包或函数就会被调用,返回值当做这个属性的默认值
//闭包结尾的大括号后接空得小括号,告诉Swift立刻执行此闭包,如果忽略这个括号,相当于闭包本身作为值赋给属性,而不是将闭包的返回值赋给属性 classSomeClass{ someProperty:SomeType={ //createadefaultvalueforsomePropertyinsIDethisclosure //someValuemustbeofthesametypeasSomeType returnsomeValue }() structCheckerboard{ boardcolors:Bool[]={ vartemporaryBoard=Bool[]() varisBlack=foriin1...10{ forjin1...10{ temporaryBoard.append(isBlack) isBlack=!isBlack returntemporaryBoard }() funcsquareIsBlackAtRow(row:Int,0); background-color:inherit">column:Int)->Bool{ returnboardcolors[(row*10)+column] letboard=Checkerboard() println(board.squareIsBlackAtRow(0,0); background-color:inherit">column:1)) //prints"true" println(board.squareIsBlackAtRow(9,0); background-color:inherit">column:9)) //prints"false"

析构过程 (Deinitialization) 类的实例被释放之前,析构函数被立即调用,deinit表示析构过程

1.原理 Swift会自动释放不需要的实例以释放资源,但当使用自己的资源的时候,需要清理额外的信息,如创建一个自定义的类来打开文件并写入数据,可能需要在类实例被释放之前关闭该文件
每个类组多只有一个析构函数,不允许主动调用,在实例被释放的前一步被自动调用,因为析构函数知道实例被释放才会被调用,所以可以访问实例的所有属性,并进行 *** 作
deinit{ //performthedeinitialization }
2. *** 作 structBank{ staticvarcoinsInBank=10_000 staticfuncvendCoins(varnumberOfCoinsTovend:Int)->Int{ numberOfCoinsTovend=min(numberOfCoinsTovend,coinsInBank) coinsInBank-=numberOfCoinsTovend returnnumberOfCoinsTovend staticfuncreceiveCoins(coins:Int){ coinsInBank+=coins classPlayer{ coinsInPurse:Int init(coins:Int){ coinsInPurse=Bank.vendCoins(coins) funcwinCoins(coins:Int){ coinsInPurse+=Bank.vendCoins(coins) deinit{ Bank.receiveCoins(coinsInPurse) playerOne:Player?=Player(coins:100) println("Anewplayerhasjoinedthegamewith\(playerOne!.coinsInPurse)coins") //prints"Anewplayerhasjoinedthegamewith100coins" println("ThereareNow\(Bank.coinsInBank)coinsleftinthebank") //prints"ThereareNow9900coinsleftinthebank" playerOne!.winCoins(2_000) println("PlayerOnewon2000coins&Nowhas\(playerOne!.coinsInPurse)coins") //prints"PlayerOnewon2000coins&Nowhas2100coins" println("ThebankNowonlyhas\(Bank.coinsInBank)coinsleft") //prints"ThebankNowonlyhas7900coinsleft" playerOne=nil println("PlayerOnehasleftthegame") //prints"PlayerOnehasleftthegame" println("ThebankNowhas\(Bank.coinsInBank)coins") //prints"ThebankNowhas10000coins" 总结

以上是内存溢出为你收集整理的Swift 构造过程+析构过程(十三)全部内容,希望文章能够帮你解决Swift 构造过程+析构过程(十三)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1081808.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存