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

Swift2-0基础_Properties(属性)

2016-04-15 18:46 573 查看
import Foundation

print("Hello, World!")

/// 1 存储属性
/*
一个存储属性就是存储在 特定类或结构体的实例里 的一个 常量或变量
可以在定义存储属性的时候制定默认值,也可以在构造过程中设置或者修改存储属性的值,甚至修改常量存储属性的值
*/
struct FixedLengthRange {
var firstValue : Int
let length : Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)  // 该区间表示 0,1,2
rangeOfThreeItems.firstValue = 6    // 6,7,8    修改变量名为firstValue的值

// 常量结构体的存储属性
// 如果创建了一个结构体的实例并将其值赋给一个常量,则无法修改该实例的任何属性,即使定义了变量存储属性
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
//rangeOfFourItems.firstValue = 2   // error
// 因为结构体是值类型 rangeOfFourItems 是常量,其属性也是常量 (类 可以修改)

// 延迟存储属性
/*
当第一次被调用的时候才会计算其初始值的属性,在属性声明前使用 lazy 来标示一个延迟存储的属性
当属性的值依赖于在实例的构造过程结束后才会知道具体的外部因素时,或者当获取属性的初始化值需要大量计算时,可以只在需要的时候计算

注意:
必须将延迟存储属性声明成变量(使用 var 关键字),因为属性的初始值可能在实例构造完成之后才会得到。
而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。
*/
class DataImporter {
/*
DataImporter 是一个将外部文件中的数据导入的类
初始化会比较耗时
*/
var fileName = "data.txt"   // 提供数据导入功能
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()   // 提供数据管理功能
}
/*
注意:
如果一个被标记为 lazy 的属性在没有初始化时就同时被多个线程访问,则无法保证该属性只会被初始化一次
*/
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// DataImporter的实例 importer 属性还没被创建

print(manager.importer.fileName)    // DataImporter的实例 importer 属性被创建

// 存储属性和实例变量
/*
Swift 编程语言中把这些理论统一用属性来实现。Swift 中的属性没有对应的实例变量,属性的后端存储也无法直接访问。
这就避免了不同场景下访问方式的困扰,同时也将属性的定义简化成一个语句。
一个类型中属性的全部信息——包括命名、类型和内存管理特征——都在唯一一个地方(类型定义中)定义
*/

// 2 计算属性
/*
除存储属性外,类、结构体和枚举可以定义计算属性。计算属性不直接存储值,而是提供一个 getter 和一个可选的 setter,
来间接获取和设置其他属性或变量的值
*/

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(newCenter) {
origin.x = newCenter.x - size.width/2
origin.y = newCenter.y - size.height/2
}
}
}
// 矩形实例
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width:10.0, height:10.0))
let initialSquareCenter = square.center
// 移动矩形
square.center = Point(x: 15.0, y: 15.0)

// 便捷 setter 声明 使用默认名称 newValue
struct AlternativeRect {
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 {
origin.x = newValue.x - size.width/2
origin.y = newValue.y - size.height/2
}
}
}

// 只读计算属性
// 只有 getter 没有setter的计算属性
/*
注意:
必须使用 var 关键字定义计算属性,包括只读计算属性,因为它们的值不是固定的.
关键字只用来声明常量属性,表示初始化后再也无法修改的值
*/
// 只读计算属性的声明可以去掉 关键字和花括号
struct Cuboid {
var width = 0.0
var height = 0.0
var depth = 0.0
var volume : Double {
return width * height * depth
}
}
let fourByFiveBySix = Cuboid(width: 4.0, height: 5.0, depth: 6.0)
print(fourByFiveBySix.volume)

// 3 属性观察器
/*
属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外
可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重写属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器

注意:
不需要为非重写的计算属性添加属性观察器,因为可以通过它的 setter 直接监控和响应值的变化

可以为属性添加如下的一个或全部观察器:
• 在新的值被设置之前调用
• didSet在新的值被设置之后立即调用

willSet 观察器会将新的属性值作为常量参数传入,在 willSet 的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称 newValue 表示。
didSet 观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名 oldValue

注意:
父类的属性在子类的构造器中被赋值时,它在父类中的 willSet 和 didSet 观察器会被调用。
*/
class StepCounter {
var totalSteps : Int = 0 {
willSet(newTotalSteps) {
print("about to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("added \(totalSteps - oldValue) steps")
}

}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// about to set totalSteps to 200
// added 200 steps
stepCounter.totalSteps = 360
// about to set totalSteps to 360
// added 160 steps

/*
注意:
如果在一个属性的 didSet 观察器里为它赋值,这个值会替换该观察器之前设置的值
*/

// 4 类型属性
/*
注意:
跟实例的存储属性不同,必须给存储型类型属性指定默认值,因为类型本身无法在初始化过程中使用构造器给类 型属性赋值。
存储型类型属性是延迟初始化的(lazily initialized),它们只有在第一次被访问的时候才会被初始化。
即使它们被多个线程同时访问,系统也保证只会对其进行初始化一次,并且不需要对其使用 lazy 修饰符。
*/
struct SomeStructure {
static var storedTypeProperty = "Some value"
static var computedTypeProperty : Int {
return 1
}
}

enum SomeEnumeration {
static var storedTypeProperty = "Some value"
static var computedTypeProperty : Int {
return 6
}
}

class SomeClass {
static var storedTypeProperty = "Some value"
static var computedTypeProperty : Int {
return 27
}
class var overrideableComputedTypeProperty : Int {
return 107
}
}

// 获取和设置类型属性的值
print(SomeStructure.storedTypeProperty)             // Some value
SomeStructure.storedTypeProperty = "Another value"
print(SomeStructure.storedTypeProperty)             // Another value
print(SomeEnumeration.computedTypeProperty)         // 6
print(SomeClass.computedTypeProperty)               // 27
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: