属性(学习笔记)
环境Xcode 11.0 beta4 swift 5.1
- 属性(Properties)
- 属性是把值和特定的类、结构体、枚举关联在一起
- 属性主要是分为存储属性(Stored Properties)和计算属性(Computed Properties)
- 存储属性是用来存储实例的常量或者变量
- 计算属性主要是用来计算值
- 计算属性可以定义在类、结构体、枚举
- 存储属性可以定义在类、结构体
- 存储属性(Stored Properties)
- 可以用
var
、let
修饰,后者一旦初始化就不可更改
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
- 结构体实例常量的存储属性,即被
let
修饰,此时的存储属性被var
修饰了不能更改,因为结构体是值类型,结构体变量的存储属性的内存是存储在结构体变量的内存中的
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property
- 延迟存储属性(Lazy Stored Properties),用
lazy
来标识且只能申明为var
,延迟存储属性是第一用到才赋值,而let
修饰的属性要在初始化前就要有值
// 以下示例代码类不是完整的类
class DataImporter {
/*
DataImporter is a class to import data from an external file.
The class is assumed to take a nontrivial amount of time to initialize.
*/
var filename = "data.txt"
// the DataImporter class would provide data importing functionality here
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// the DataManager class would provide data management functionality here
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance for the importer property has not yet been created
print(manager.importer.filename)
// the DataImporter instance for the importer property has now been created
// Prints "data.txt"
- 存储属性&实例变量,在OC中有两种方式存储值和类的实例对象,即属性和实例变量(即成员变量);Swift统一了这些概念,属性的所有信息(包括它的名称、类型和内存管理特性)都在类型定义的时候,作为类型的一部分定义在类型中
- 计算属性(Computed Properties)
- 计算属性不是真的用来存储值,而是提供
getter
和setter
(可选)去获取和设置其它属性和值
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, 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)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.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声明(隐式返回即省略
return
)
struct CompactRect {
var origin = Point()
var size = Size()
var center: Point {
get {
Point(x: origin.x + (size.width / 2),
y: origin.y + (size.height / 2))
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
- 只读计算属性(Read-Only Computed Properties),只有
getter
,没有setter
,可以用var
修饰,getter
也可以省略不写
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// Prints "the volume of fourByFiveByTwo is 40.0"
- 属性观察器(Property Observers)
- 观察和响应属性值的变化,即使设置的是相同的值也会触发;
- 可以为任意的属性添加属性观察器,延迟存储属性除外
- 可以在子类为任意继承属性(存储或计算属性)添加属性观察器
- 非重写的计算属性不需要定义属性观察器,可以在setter中观察和响应
- 可以在属性上添加
willSet
(在值存储前调用,自带一个常量参数newValue
)didSet
(新设置的值存储立即调用,自带一个常量参数oldValue
)
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) { // 不用默认的newValue,自定义一个参数
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
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
- 传递一个属性给一个
in-out
参数,willSet
didSet
都会被调用,这是因为in-out
参数的copy-in copy-out
内存管理,在函数调用的最后总是会将值写加给属性
- 全局和局部变量(Global and Local Variables)
- 全局和局部变量都可以设置计算属性和属性观察器
- 全局常量和变量总是延迟计算,类似延迟存储属性,但不需要
lazy
修饰 - 局部常量和变量从不是延迟计算的
- 类型属性(Type Properties)
- 是线程安全的
- 计算类型属性总是变量(同计算实例属性)和存储类型属性可以是变量或常量
- 用
static
关键字修饰,由class
定义的类可以用class
关键字标识类型属性,以便子类重写
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)
// Prints "Some value."
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// Prints "Another value."
print(SomeEnumeration.computedTypeProperty)
// Prints "6"
print(SomeClass.computedTypeProperty)
// Prints "27"
属性(学习笔记)
环境Xcode 11.0 beta4 swift 5.1
- 属性(Properties)
- 属性是把值和特定的类、结构体、枚举关联在一起
- 属性主要是分为存储属性(Stored Properties)和计算属性(Computed Properties)
- 存储属性是用来存储实例的常量或者变量
- 计算属性主要是用来计算值
- 计算属性可以定义在类、结构体、枚举
- 存储属性可以定义在类、结构体
- 存储属性(Stored Properties)
- 可以用
var
、let
修饰,后者一旦初始化就不可更改
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
- 结构体实例常量的存储属性,即被
let
修饰,此时的存储属性被var
修饰了不能更改,因为结构体是值类型,结构体变量的存储属性的内存是存储在结构体变量的内存中的
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property
- 延迟存储属性(Lazy Stored Properties),用
lazy
来标识且只能申明为var
,延迟存储属性是第一用到才赋值,而let
修饰的属性要在初始化前就要有值
// 以下示例代码类不是完整的类
class DataImporter {
/*
DataImporter is a class to import data from an external file.
The class is assumed to take a nontrivial amount of time to initialize.
*/
var filename = "data.txt"
// the DataImporter class would provide data importing functionality here
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// the DataManager class would provide data management functionality here
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance for the importer property has not yet been created
print(manager.importer.filename)
// the DataImporter instance for the importer property has now been created
// Prints "data.txt"
- 存储属性&实例变量,在OC中有两种方式存储值和类的实例对象,即属性和实例变量(即成员变量);Swift统一了这些概念,属性的所有信息(包括它的名称、类型和内存管理特性)都在类型定义的时候,作为类型的一部分定义在类型中
- 计算属性(Computed Properties)
- 计算属性不是真的用来存储值,而是提供
getter
和setter
(可选)去获取和设置其它属性和值
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, 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)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.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声明(隐式返回即省略
return
)
struct CompactRect {
var origin = Point()
var size = Size()
var center: Point {
get {
Point(x: origin.x + (size.width / 2),
y: origin.y + (size.height / 2))
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
- 只读计算属性(Read-Only Computed Properties),只有
getter
,没有setter
,可以用var
修饰,getter
也可以省略不写
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// Prints "the volume of fourByFiveByTwo is 40.0"
- 属性观察器(Property Observers)
- 观察和响应属性值的变化,即使设置的是相同的值也会触发;
- 可以为任意的属性添加属性观察器,延迟存储属性除外
- 可以在子类为任意继承属性(存储或计算属性)添加属性观察器
- 非重写的计算属性不需要定义属性观察器,可以在setter中观察和响应
- 可以在属性上添加
willSet
(在值存储前调用,自带一个常量参数newValue
)didSet
(新设置的值存储立即调用,自带一个常量参数oldValue
)
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) { // 不用默认的newValue,自定义一个参数
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
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
- 传递一个属性给一个
in-out
参数,willSet
didSet
都会被调用,这是因为in-out
参数的copy-in copy-out
内存管理,在函数调用的最后总是会将值写加给属性
- 全局和局部变量(Global and Local Variables)
- 全局和局部变量都可以设置计算属性和属性观察器
- 全局常量和变量总是延迟计算,类似延迟存储属性,但不需要
lazy
修饰 - 局部常量和变量从不是延迟计算的
- 类型属性(Type Properties)
- 是线程安全的
- 计算类型属性总是变量(同计算实例属性)和存储类型属性可以是变量或常量
- 用
static
关键字修饰,由class
定义的类可以用class
关键字标识类型属性,以便子类重写
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)
// Prints "Some value."
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// Prints "Another value."
print(SomeEnumeration.computedTypeProperty)
// Prints "6"
print(SomeClass.computedTypeProperty)
// Prints "27"
属性(学习笔记)
环境Xcode 11.0 beta4 swift 5.1
- 属性(Properties)
- 属性是把值和特定的类、结构体、枚举关联在一起
- 属性主要是分为存储属性(Stored Properties)和计算属性(Computed Properties)
- 存储属性是用来存储实例的常量或者变量
- 计算属性主要是用来计算值
- 计算属性可以定义在类、结构体、枚举
- 存储属性可以定义在类、结构体
- 存储属性(Stored Properties)
- 可以用
var
、let
修饰,后者一旦初始化就不可更改
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8
- 结构体实例常量的存储属性,即被
let
修饰,此时的存储属性被var
修饰了不能更改,因为结构体是值类型,结构体变量的存储属性的内存是存储在结构体变量的内存中的
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property
- 延迟存储属性(Lazy Stored Properties),用
lazy
来标识且只能申明为var
,延迟存储属性是第一用到才赋值,而let
修饰的属性要在初始化前就要有值
// 以下示例代码类不是完整的类
class DataImporter {
/*
DataImporter is a class to import data from an external file.
The class is assumed to take a nontrivial amount of time to initialize.
*/
var filename = "data.txt"
// the DataImporter class would provide data importing functionality here
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// the DataManager class would provide data management functionality here
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance for the importer property has not yet been created
print(manager.importer.filename)
// the DataImporter instance for the importer property has now been created
// Prints "data.txt"
- 存储属性&实例变量,在OC中有两种方式存储值和类的实例对象,即属性和实例变量(即成员变量);Swift统一了这些概念,属性的所有信息(包括它的名称、类型和内存管理特性)都在类型定义的时候,作为类型的一部分定义在类型中
- 计算属性(Computed Properties)
- 计算属性不是真的用来存储值,而是提供
getter
和setter
(可选)去获取和设置其它属性和值
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, 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)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.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声明(隐式返回即省略
return
)
struct CompactRect {
var origin = Point()
var size = Size()
var center: Point {
get {
Point(x: origin.x + (size.width / 2),
y: origin.y + (size.height / 2))
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
- 只读计算属性(Read-Only Computed Properties),只有
getter
,没有setter
,可以用var
修饰,getter
也可以省略不写
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// Prints "the volume of fourByFiveByTwo is 40.0"
- 属性观察器(Property Observers)
- 观察和响应属性值的变化,即使设置的是相同的值也会触发;
- 可以为任意的属性添加属性观察器,延迟存储属性除外
- 可以在子类为任意继承属性(存储或计算属性)添加属性观察器
- 非重写的计算属性不需要定义属性观察器,可以在setter中观察和响应
- 可以在属性上添加
willSet
(在值存储前调用,自带一个常量参数newValue
)didSet
(新设置的值存储立即调用,自带一个常量参数oldValue
)
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) { // 不用默认的newValue,自定义一个参数
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
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
- 传递一个属性给一个
in-out
参数,willSet
didSet
都会被调用,这是因为in-out
参数的copy-in copy-out
内存管理,在函数调用的最后总是会将值写加给属性
- 全局和局部变量(Global and Local Variables)
- 全局和局部变量都可以设置计算属性和属性观察器
- 全局常量和变量总是延迟计算,类似延迟存储属性,但不需要
lazy
修饰 - 局部常量和变量从不是延迟计算的
- 类型属性(Type Properties)
- 是线程安全的
- 计算类型属性总是变量(同计算实例属性)和存储类型属性可以是变量或常量
- 用
static
关键字修饰,由class
定义的类可以用class
关键字标识类型属性,以便子类重写
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)
// Prints "Some value."
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// Prints "Another value."
print(SomeEnumeration.computedTypeProperty)
// Prints "6"
print(SomeClass.computedTypeProperty)
// Prints "27"