//: Playground - noun: a place where people can play import UIKit //---属性-------// //1.结构体的属性 struct MyRange { var location : Int //变量属性 let length: Int //常量属性 } //如果没有给定属性的初值,则实例化结构体需要使用逐一构造器进行构造 var range1 = MyRange(location: 0, length: 3) print(range1) range1.location = 2 //range1.length = 7 let range2 = MyRange(location: 3, length: 9) //range2.location = 4 //2.类的属性 //必须具有初始值 class Door { var color : String = "Black" let width : Int = 2 let Height : Int = 3 var isLocked : Bool? //如果不初始化则可以将属性设置成可选类型 //Swift中的构造器,类似于OC中的init初始化方法 init() { print("Door init") } } var door1 = Door() //print(door1.color) //print(door1.isLocked) //3.延迟存储属性,懒加载 class ImageData { var fileName = "image.png" init() { //把本地名字为fileName的图片读取出来 //图片较大,比较耗时 print("ImageData init方法:把数据从图片文件中读取出来") } } class DataManager { var data = [String]() lazy var image = ImageData() init() { print("DataManager init方法") } } let dataManager = DataManager() dataManager.image.fileName //在创建DataManager时先不需要去构造image实例,而是在使用到image实例时才去创建它,提高程序的执行效率。 //必须声明懒惰存储属性为变量属性(var),因为它的初始值直到实例初始化完成之后才被检索。 //常量属性(let)在实例初始化完成之前就应该被赋值,因此常量属性不能够被声明为懒惰存储属性。 //4.计算属性 //存储属性:作为实例的一部分,存储常量或者变量的值。 //计算属性:只是计算属性的值,不仅是存储。 //计算属性可用于类,结构体,枚举,而存储属性只能用类和结构体。 //class Student { // // var name:String? // // var age:Int { // // //getter方法 // get { // return 10 // } // // //setter方法 // set (newAge) { // //newAge是新设置的值 // print("newAge=(newAge)") // // } // // // } // //} // //var stu = Student() //stu.age = 10 //print(stu.age) struct Point { var x = 0.0 var y = 0.0 } struct Size { var width = 0.0 var height = 0.0 } struct Rect { var origin = Point() var size = Size() //这个属性可以直接计算出来,不需要额外的存储 var center : Point { get { let centerX = origin.x + size.width/2 let centerY = origin.y + size.height/2 return Point(x: centerX, y: centerY) } //计算属性的set方法中有一个隐含的形参,名字叫做newValue,代表传入的新值 set { //通过新的中心点坐标来改变起点的的坐标,最终达到改变rect显示位置的目的 origin.x = newValue.x - size.width/2 origin.y = newValue.y - size.height/2 } } } var point1:Point = Point() var size1:Size = Size( 100, height: 100) var rect1 = Rect(origin: point1, size: size1) var center1 = rect1.center print(center1) //通过计算属性的get方法来获取到center的值 center1.x = 30 center1.y = 30 rect1.center = center1 //调用setter方法 print(rect1.origin) //计算属性不存储数据,只是提供访问和设置数据的接口 //只提供getter,不提供setter,即只读的计算属性 //只提供setter,不提供getter,语法上不允许 struct Cube { var width = 0.0 var height = 0.0 var depth = 0.0 var cul : Double { //get { //当计算属性只读时,可以把get关键字省略 return width * height * depth //} } } var cube = Cube( 10, height: 10, depth: 10) //cube.cul = 10000 //5.属性观察者,类似于OC中的KVO //Swift提供两种方法willSet和didSet,可以监听属性值的前后变化 class StepCounter { var totalCounts : Int = 100 { //这个属性值被设置之前会调用 willSet { //不能在willSet中改变监听的属性值,容易引起死循环 //totalCounts += newValue; print("totalValue的新值=(newValue)") } //这个属性值设置之后立即被调用 didSet { //didSet中可以改变监听的属性值,因为其在设置属性值之后才会被调用 totalCounts += oldValue; print("totalValue的旧值=(oldValue)") } //如果没有指定willSet和didSet的参数,系统会默认生成一组newValue表示新值,oldValue表示旧值 } } let step = StepCounter() step.totalCounts = 200