属性

  • 属性将值跟特定的类、结构或枚举关联。存储属性存储常量或变量作为实例的一部分,而计算属性计算(不是存储)一个值。计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。
  • 存储属性和计算属性通常与特定类型的实例关联。但是,属性也可以直接作用于类型本身,这种属性称为类型属性。
  • 另外,还可以定义属性观察器来监控属性值的变化,以此来触发一个自定义的操作。属性观察器可以添加到自己定义的存储属性上,也可以添加到从父类继承的属性上。

存储属性

存储属性顾名思义就是存储在类和结构体中的常量或变量,当定义存储属性的时候可以给存储属性设定初始值,也可以在构造过程中设置值或改变值,

// 声明一个结构体
struct CustomRange {
// 以下的代码定义了两个属性,一个为变量 一个为常量 并且都没有设置初始值
var firstValue: Int
let length: Int
} // 可以调用逐一构造方法给定初始值
var range = CustomRange(firstValue: 5, length: 6) // 因为firstValue是变量 可以在初始化之后修改值
range.firstValue = 6

注意:由于结构体是值类型,如果实例化一个常量结构体的话,不可以修改结构体中的变量属性,否则会报错:

let otherRange = CustomRange(firstValue: 3, length: 5)
otherRange.firstValue = 5 // 此行代码会报错 因为otherRange被声明为常量,即使firstValue属性是变量也不可以修改

延迟存储属性

延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。当属性的值依赖于在实例的构造过程结束后才会知道具体值的外部因素时,或者当获得属性的初始值需要复杂或大量计算时,可以只在需要的时候计算它。声明延迟存储属性用<lazy>关键字,并且必须设置为变量(var)

// 例如有一个文件下载器 初始化这个下载器会消耗大量的时间和资源
class DataDownloader {
var fileName: String? func start() {
fileName = "swift.data"
}
} // 例如有一个文件管理者
class DataManager {
// 因为之前假设下载器的初始化会消耗大量时间和资源 所以使用lazy
lazy var downloader = DataDownloader()
var search = [String]()
} // 初始化了文件管理者 这时downloader还没有被调用 所以Downloader不会有值
var manager = DataManager() manager.search.append("some data") // 此时到了下面这行代码 downloader才会被初始化
manager.downloader.start()

计算属性

除存储属性外,类、结构体和枚举可以定义计算属性。计算属性不直接存储值,而是提供一个 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() // 定义center属性 center属性不做任何存储 只是在get 和 set方法中对origin的值进行计算后修改
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
}
// 下面的set方法和上面的等效 就是为新的值取了个名字
// set (newCenter) {
// origin.x = newCenter.x - size.width / 2
// origin.y = newCenter.y - size.height / 2
// }
}
}

只读计算属性

只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访问,但不能设置新的值。

class Rectangle {
var length = 1.0, width = 2.0, height = 5.0
// var volume: Double {
// get {
// return length * width * height
// }
// }
// 一般只有getter方法时可以像下面代码这么写,当然上面的也可以
var volume: Double {
return length * width * height
}
} let rectangle: Rectangle = Rectangle()
print("volume is \(rectangle.volume)")
// 打印出: volume is 10.0

属性观察器

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

class Person {
var name: String = "ASK" {
willSet {
print("the new name is \(newValue)")
}
didSet{
if name == "" {
name = oldValue
}
print("did set the old name is \(oldValue) and the current name is \(name)")
}
}
} let person = Person() person.name = "Alex"
// 打印: the new name is Alex
// did set the old name is ASK and the current name is Alex

注意: 如果在didset方法中为属性赋值的话 那么这个值会替换掉该观察器之前的值

如果将name属性赋为""(空串)  ↓

person.name = ""
// 打印: the new name is
// did set the old name is ASK and the current name is ASK

类型属性

在 C 或 Objective-C 中,与某个类型关联的静态常量和静态变量,是作为全局(global)静态变量定义的。但是在 Swift 编程语言中,类型属性是作为类型定义的一部分写在类型最外层的花括号内,因此它的作用范围也就在类型支持的范围内。

使用关键字static来定义类型属性。在为类(class)定义计算型类型属性时,可以使用关键字class来支持子类对父类的实现进行重写。下面的例子演示了存储型和计算型类型属性的语法:

class SomeClass {
static var name = "class name" {
willSet {
print("static property will set name value")
}
}
// 写成class代表子类可以重写 枚举可结构体不可以这么写
class var overrideProperty: Int {
return SomeClass.name.characters.count
}
} print("name is \(SomeClass.name) length is \(SomeClass.overrideProperty)")
SomeClass.name = "the some class"
print("name is \(SomeClass.name) length is \(SomeClass.overrideProperty)")
// 打印 1 name is class name length is 10
// 2 static property will set name value
// 3 name is the some class length is 14

学习Swift--属性的更多相关文章

  1. Swift 学习笔记 (属性)

    属性可以将值与特定的类 结构体 或者枚举联系起来. 存储属性会存储常量或者变量作为实例的一部分.反之计算属性会计算(而不是存储值)值. 计算属性可以由类 结构体 和枚举定义.存储属性只能由类和结构体定 ...

  2. ios -- 教你如何轻松学习Swift语法(三) 完结篇

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.自动引用计数   1.自动引用计数工作机制      1.1 swift和o ...

  3. ios -- 教你如何轻松学习Swift语法(二)

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.可选类型(重点内容)   1.什么是可选类型?        1.1在OC开 ...

  4. ios -- 教你如何轻松学习Swift语法(一)

    目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类 ...

  5. 一步一步学习Swift之(一):关于swift与开发环境配置

    一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Sw ...

  6. 開始学习swift开发

    近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.

  7. 学习swift语言的快速入门教程推荐

    随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...

  8. 一步一步学习Swift之(二):好玩的工具playground与swfit基础语法

    playground好于在于能一边写代码一边看到输出的常量变量的值.不需要运行模拟器. 我们来试一下该工具的用法. 打开xcode6开发工具,选择Get started with a playgrou ...

  9. 開始学习swift,资料汇总帖

    最近開始学习swift,以后mac和ios开发就指望它,曾经学oc半途而废了.主要原因是oc等语法实在能适应,如今有swift了.语法有js,scala,python,c++,oc等语言的影子,又一次 ...

  10. Swift-如何快速学习Swift

    关于本文: 1.说明本文写作的目的 2.整理了Swift的基本语法树 3.看图作文 一.写作目的 昨天看了一个知识专栏,作者讲述的是“如何研究性的学习”.整个课程1个小时9分钟,花了我19块人民币.其 ...

随机推荐

  1. Hibernate—第一个案例

    百度百科上是这样写道的:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可 ...

  2. 转 python 之 分割参数getopt

    python 之 分割参数getopt os下有个方法walk,非常的好用,用来生成一个generator.每次可以得到一个三元tupple,其中第一个为起始路径,第二个为起始路径下的文件夹,第三个是 ...

  3. WCF客户端和服务器时间不一致,导致通道建立失败的问题)

    本文转载:http://www.cnblogs.com/bcbr/articles/2288374.html 最近,经常有客户反应,前天还用的好好的系统,今天就不能用了. 考虑到系统近来没有做过改动和 ...

  4. jbpm6 开发环境搭建

     一.软件下载 1. eclipse       下载地址:http://www.eclipse.org/downloads/ 2.jbpm6.2 Installer       下载地址: ht ...

  5. 安装Win7和Ubuntu12.04双系统后,意外删除Ubuntu12.04引导文件,出现error:unknown filesystem;grub rescue>错误的解决方案

    很久之前在Win7基础上安装了Ubuntu12.04系统,采用硬盘安装的方法.分了1个10G的硬盘分区F盘用于存放Ubuntu12.04的引导文件,其实完全可以制作一个Ubuntu12.04的U盘启动 ...

  6. System Operations on AWS - Lab 6W - Using Auto Scaling (Windows)

    创建你的一个web server,然后将这个实例制成你的AMI,通过启动配置生成一个Auto Scaling组(包括scale-in/scale-out策略),配置一台Load Balancer指向你 ...

  7. Mysql内存表的用处

    文章出自:http://blog.csdn.net/hitzhang/article/details/5994639 个人最欣赏mysql的地方就是他存储引擎的多样性和可扩展性,这样mysql也能拥有 ...

  8. java - String 浅谈

    /** * String s1 = "a"; * 编译器会先检查常量池中是否已经有"a": * 如果没有,则在常量池先创建,后引用. * 如果有,则直接引用; ...

  9. Redhat linux DNS配置指南(SCANIP配置手册)

    在oracle 11g的RAC中增加了SCAN IP,而使用 SCAN IP的一种方式就是使用DNS,这里介绍在Redhat Linux 5.4中DNS的详细配置操作在配置DNS之前修改主机名Redh ...

  10. Gulp-入门教程 搭配环境

    之前一直听朋友谈起gulp,但没有使用过,最近有机会接触到,现在给大家分享下,不对的地方还请指正.我一直以为互相分享是学习的一种好方式.下面进入正题: 首先来了解下gulp,最起码要知道:我们为什么要 ...