Swift4 基础部分: Properties

本文是学习《The Swift Programming Language》整理的相关随笔,基本的语法不作介绍,主要介绍Swift中的一些特性或者与OC差异点。

系列文章:

常量的结构体实例的属性(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:
  • 常量的结构体实例的属性即使是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.
  • 如果一个结构体实例被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.
  • 延迟存储属性只有当使用时才会被创建,用lazy关键字修饰

例子:

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)

执行结果:

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.
  • 除了存储属性,类与结构体,枚举都可以定义计算属性,计算属性是一个可选的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))")

执行结果:

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. 
  • 当属性发生变化时会触发属性观察器,可以给除了延迟存储属性的属性添加观察器。同样子类继承的属性一样也可以添加观察器,只需要子类中重载属性即可。
  • 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 = 10
stepCounter.totalSteps = 20

执行结果:

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.
  • 全局变量是在函数、方法、闭包或任何类型之外定义的变量,局部变量是在函数、方法或闭包内部定义的变量。

例子:

var globalNum = 0;
func changeNumToTen(){
    var localNum = 10;
    globalNum = 10;
    print("globalNum:\(globalNum) localNum:\(localNum)");
}

changeNumToTen();
globalNum = 20;
print("globalNum:\(globalNum)");

执行结果:

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. 
  • 使用关键字static来定义类型属性,另外可以以使用关键字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)

执行结果:

Some value.
Another value.
6
27
107
108
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,375评论 6 343
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • Swift语法基础(五)-- (类和结构体、属性、方法) 本章将会介绍 类和结构体对比结构体和枚举是值类型类是引用...
    寒桥阅读 1,055评论 0 1
  • 我每天使用 Git ,但是很多命令记不住。一般来说,日常使用只要记住下图6个命令,就可以了。但是熟练使用,恐怕要记...
    Smallwolf_JS阅读 340评论 0 2
  • 等你的日子缓慢悠长, 荷叶刚醒,晨光熹微。 我在等你, 你 不知道。 在街上徘徊, 想着此刻的你在哪? 该走哪条路...
    慎何阅读 307评论 6 3