本文是學(xué)習(xí)《The Swift Programming Language》整理的相關(guān)隨筆蓖康,基本的語法不作介紹铐炫,主要介紹Swift中的一些特性或者與OC差異點。
系列文章:
常量的結(jié)構(gòu)體實例的屬性(Stored Properties of Constant Structure Instances)
If you create an instance of a structure and assign that
instance to a constant, you cannot modify the instance’s
properties, even if they were declared as variable
properties:
- 常量的結(jié)構(gòu)體實例的屬性即使是
var
修飾也不能更改它的值
例子:
struct FixedLengthRange{
var firstValue:Int
let length:Int
}
let rangeOfFourItems = FixedLengthRange(firstValue:0,length:4)
rangeOfFourItems.firstValue = 6;
編譯錯誤:
error: MyPlayground.playground:527:29: error: cannot assign to property: 'rangeOfFourItems' is a 'let' constant
rangeOfFourItems.firstValue = 6;
~~~~~~~~~~~~~~~~ ^
MyPlayground.playground:526:1: note: change 'let' to 'var' to make it mutable
let rangeOfFourItems = FixedLengthRange(firstValue:0,length:4)
^~~
原因:
Because rangeOfFourItems is declared as a constant (with
the let keyword), it is not possible to change its
firstValue property, even though firstValue is a variable
property.
This behavior is due to structures being value types. When
an instance of a value type is marked as a constant, so
are all of its properties.
- 如果一個結(jié)構(gòu)體實例被
constant
修飾蒜焊,它的所有屬性也是默認的常量
延遲存儲屬性(Lazy Stored Properties)
A lazy stored property is a property whose initial value
is not calculated until the first time it is used. You
indicate a lazy stored property by writing the lazy
modifier before its declaration.
- 延遲存儲屬性只有當(dāng)使用時才會被創(chuàng)建倒信,用
lazy
關(guān)鍵字修飾
例子:
class DataImporter{
var filename = "data.txt"
}
class DataManager{
lazy var importer = DataImporter()
var data = [String]()
}
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
print(manager.importer.filename)
執(zhí)行結(jié)果:
someVideoMode === otherVideoMode
someVideoMode !== thirdVideoMode
data.txt
計算屬性(Computed Properties)
In addition to stored properties, classes, structures, and
enumerations can define computed properties, which do not
actually store a value. Instead, they provide a getter and
an optional setter to retrieve and set other properties
and values indirectly.
- 除了存儲屬性,類與結(jié)構(gòu)體泳梆,枚舉都可以定義計算屬性鳖悠,計算屬性是一個可選的
setter
來間接設(shè)置其他屬性或變量的值
例子:
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))")
執(zhí)行結(jié)果:
square.origin is now at (10.0, 10.0)
便捷的Setter聲明(Shorthand Setter Declaration)
If a computed property’s setter does not define a name for
the new value to be set, a default name of newValue is
used. Here’s an alternative version of the Rect structure,
which takes advantage of this shorthand notation:
- 如果一個計算屬性的的set方法沒有定義一個新的名字給這個新的值,那么默認的名字就是
newValue
例子:
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{
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
只讀的計算屬性(Read-Only Computed Properties)
A computed property with a getter but no setter is known
as a read-only computed property. A read-only computed
property always returns a value, and can be accessed
through dot syntax, but cannot be set to a different
value.
- 計算屬性如果只寫入了get方法沒有set方法优妙,那么就是只讀的計算屬性
例子:
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)")
例子:
the volume of fourByFiveByTwo is 40.0
屬性觀察器(Property Observers)
Property observers observe and respond to changes in a
property’s value. Property observers are called every
time a property’s value is set, even if the new value is
the same as the property’s current value.
You can add property observers to any stored properties
you define, except for lazy stored properties. You can
also add property observers to any inherited property
(whether stored or computed) by overriding the property
within a subclass. You don’t need to define property
observers for nonoverridden computed properties, because
you can observe and respond to changes to their value in
the computed property’s setter. Property overriding is
described in Overriding.
You have the option to define either or both of these
observers on a property:
- willSet is called just before the value is stored.
- didSet is called immediately after the new value is
stored.
- 當(dāng)屬性發(fā)生變化時會觸發(fā)屬性觀察器乘综,可以給除了延遲存儲屬性的屬性添加觀察器。同樣子類繼承的屬性一樣也可以添加觀察器套硼,只需要子類中重載屬性即可卡辰。
-
willSet
當(dāng)屬性將要變化是觸發(fā) -
didSet
當(dāng)屬性已經(jīng)發(fā)生變化時觸發(fā)
例子:
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 = 10
stepCounter.totalSteps = 20
執(zhí)行結(jié)果:
About to set totalSteps to 10
Added 10 steps
About to set totalSteps to 20
Added 10 steps
全局變量與局部變量(Global and Local Variables)
Global variables are variables that are defined outside of
any function, method, closure, or type context. Local
variables are variables that are defined within a function,
method, or closure context.
- 全局變量是在函數(shù)、方法、閉包或任何類型之外定義的變量九妈,局部變量是在函數(shù)朴恳、方法或閉包內(nèi)部定義的變量。
例子:
var globalNum = 0;
func changeNumToTen(){
var localNum = 10;
globalNum = 10;
print("globalNum:\(globalNum) localNum:\(localNum)");
}
changeNumToTen();
globalNum = 20;
print("globalNum:\(globalNum)");
執(zhí)行結(jié)果:
globalNum:10 localNum:10
globalNum:20
類型屬性(Type Properties)
Instance properties are properties that belong to an instance
of a particular type. Every time you create a new instance of
that type, it has its own set of property values, separate
from any other instance.
You can also define properties that belong to the type
itself, not to any one instance of that type. There will only
ever be one copy of these properties, no matter how many
instances of that type you create. These kinds of properties
are called type properties.
- 類型本身可以定義屬性允蚣,不管有多少個實例于颖,這些屬性只有唯一一份
類型屬性語法(Type Property Syntax)
You define type properties with the static keyword. For
computed type properties for class types, you can use the
class keyword instead to allow subclasses to override the
superclass’s implementation.
- 使用關(guān)鍵字
static
來定義類型屬性,另外可以以使用關(guān)鍵字class
來定義計算類型屬性嚷兔,讓子類可以重寫該方法(使用static
的計算屬性不能被重寫)
例子:
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;
}
}
class SubSomeClass:SomeClass{
override class var overrideableComputedTypeProperty: Int {
return 108;
}
}
print(SomeStructure.storedTypeProperty)
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
print(SomeEnumeration.computedTypeProperty)
print(SomeClass.computedTypeProperty)
print(SomeClass.overrideableComputedTypeProperty)
print(SubSomeClass.overrideableComputedTypeProperty)
執(zhí)行結(jié)果:
Some value.
Another value.
6
27
107
108