//属性

import UIKit

//属性(Properties)详解

/*

存储属性(Stored Properties):类、结构体中,不能在枚举中

计算属性(Computed Properties):类、结构体、枚举中,只能定义为变量

1.计算属性不直接存储值,而是提供一个 get{...return...} 和一个可选的 set(newValue){...},来间接获取和设置其他属性或变量的值。

2.必须定义为变量var,包括只读计算属性,因为它们的值不是固定的

延迟属性:当第一次被调用的时候才会计算其初始值的属性,用lazy来标示

1.必须将延迟存储属性声明成变量(var),因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

2.使用情况:当属性的值依赖于在实例的构造过程结束后才会知道具体值的外部因素时,或者当获得属性的初始值需要复杂或大量计算时,可以只在需要的时候计算它

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

1.willSet在新的值被设置之前调用,将新的属性值作为常量参数传入,可以为该参数命名或者使用默认参数名newValue

2.didSet在新的值被设置之后立即调用,将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue

3.父类的属性在子类的构造器中被赋值时,它在父类中的willSet和didSet观察器会被调用

全局变量和局部变量(Global and Local Variables):

1.全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。

2.在全局或局部范围都可以定义计算型变量和为存储型变量定义观察器。计算型变量跟计算属性一样,返回一个计算结果而不是存储值,声明格式也完全一样。

3.全局的常量或变量都是延迟计算的,跟延迟存储属性相似,不同的地方在于,全局的常量或变量不需要标记lazy修饰符,局部范围的常量或变量从不延迟计算

类型属性(Type Properties):声明关键字static,通过类型本身来调用,而非通过实例调用(C语言中称静态)

1.为某个类型本身定义的属性,用于定义某个类型所有实例共享的数据,无论创建多少个实例,这些类型属性都只有唯一的一份,可为常量或变量

2.必须给存储型类型的类型属性指定默认值,因为类型本身没有构造器,也就无法在初始化过程中使用构造器给类型属性赋值。

3.存储型类型属性是延迟初始化的,它们只有在第一次被访问的时候才会被初始化,即使它们被多个线程同时访问,系统也保证只会对其进行一次初始化,并且不需要对其使用lazy修饰符。

4.在为类定义计算型类型属性时,可以改用关键字class来支持子类对父类的实现进行重写

可延迟小结:

1.延迟属性,用lazy var定义的属性

2.自动闭包,延迟执行,只有被调用时才执行

3.全局变量或常量,是延迟计算的,不用lazy标记

4.存储型的类型属性,是延迟初始化的,第一次被访问时才会被初始化

5.指定清理操作:defer{...}内的语句的执行延迟到当前的作用域退出之前

*/

struct Point {

var x = 0.0, y = 0.0

}

struct Size {

var width = 0.0, height = 0.0

}

struct Cuboid {

lazy var yanchi = Point(x:1.0,y:2.0)  //延迟属性,只有在被调用时才创建

var width = 0.0, height = 0.0, depth = 0.0

var volume: Double {           //属性volume为只读计算属性,它省略了get和{}

return width * height * depth

}

}

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) {        //set默认参数为(newValue),可省略,也可以自定义参数名

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  //调用get来获得值

square.center = Point(x: 15.0, y: 15.0)  //调用set来设置值

print("square.origin is now at (\(square.origin.x), \(square.origin.y))")

// 输出 "square.origin is now at (10.0, 10.0)”

//=============观察器===================

class StepCounter {

var totalSteps: Int = 0 {

willSet(newTotalSteps) {

print("更改之前为:\(totalSteps) 更改之后为:\(newTotalSteps)")

}

didSet {

if totalSteps > oldValue  {

print("改完后的值为:\(totalSteps),新值-旧值=\(totalSteps - oldValue)")

}

}

}

}

let stepCounter = StepCounter()

stepCounter.totalSteps = 200   //存储属性totalSteps的值被改为200之前先调用willSet,改完后调用didSet

stepCounter.totalSteps = 896

//==============类型属性=====================

struct SomeStructure {

static var storedTypeProperty = "Some value."   //必须为所有的static的存储类型赋初始值

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"

//==========

struct AudioChannel {

static let thresholdLevel = 10

static var maxInputLevelForAllChannels = 0

var currentLevel: Int = 0 {

didSet {

if currentLevel > AudioChannel.thresholdLevel {

currentLevel = AudioChannel.thresholdLevel

}

if currentLevel > AudioChannel.maxInputLevelForAllChannels {

AudioChannel.maxInputLevelForAllChannels = currentLevel

}

}

}

}

var leftChannel = AudioChannel()

var rightChannel = AudioChannel()

leftChannel.currentLevel = 7

print(leftChannel.currentLevel)

// 输出 "7"

print(AudioChannel.maxInputLevelForAllChannels)

// 输出 "7"

rightChannel.currentLevel = 11

print(rightChannel.currentLevel)

// 输出 "10"

print(AudioChannel.maxInputLevelForAllChannels)

// 输出 "10"

swift学习笔记之-属性的更多相关文章

  1. Swift学习笔记(13)--属性 (Properties)

    普通属性用var和let即可,本文不做详述 1.延迟存储属性 延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性.在属性声明前使用@lazy来标示一个延迟存储属性. class DataImp ...

  2. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  3. Swift学习笔记(一)搭配环境以及代码运行成功

    原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...

  4. swift学习笔记之--类的计算属性

    1,Swift中类可以使用计算属性,即使用get和set来间接获取/改变其他属性的值,代码如下 class Calcuator{ ; ; var sum:Int{ get{ return a + b ...

  5. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  6. swift学习笔记4——扩展、协议

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  7. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  8. swift学习笔记1——基础部分

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  9. 记录:swift学习笔记1-2

    swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...

随机推荐

  1. Java中不同的并发实现的性能比较

    Fork/Join框架在不同配置下的表现如何? 正如即将上映的星球大战那样,Java 8的并行流也是毁誉参半.并行流(Parallel Stream)的语法糖就像预告片里的新型光剑一样令人兴奋不已.现 ...

  2. 设计宝库:22套精美的 PhotoShop 素材免费下载

    <设计宝库>系列给大家带来22套精美的 PSD 设计素材,你可以免费下载使用.设计师经常会去网上搜罗各种各样的素材,这些免费素材不仅能帮助他们节省大量的时间,而且能有很好的效果.非常感谢那 ...

  3. 自制简单的.Net ORM框架 (一) 简介

    在自己研究ORM之前,也使用过几个成熟的ORM方案,例如:EntityFramework,PetaPoco,Dapper 等,用是很好用,但是对自己来说总是不那么方便,EF比较笨重,Dapper要自定 ...

  4. JAVA 设计模式 外观模式

    用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  5. 用Android模拟器也可以开发和测试NFC应用

    从Android2.3开始支持NFC.不过NFC应用只能在Android手机(或平板电脑)上测试和开发,而且Android手机还必须有NFC芯 片.而且如果测试NFC传输文件时至少需要两部支持NFC的 ...

  6. C#基础03

    学习集合的一些知识.集合:泛型集合,非泛型集合;ArrayList,Hashtable,List<T>,Dictionary<k,v>等,还有一些集合的常用方法. 一:集合的介 ...

  7. 正则表达式匹配a标签的href

    JS代码: <html> <head> <script language="javascript"> var a='<P><A ...

  8. C#基础-replace()过滤非法字符

    string FilterfileName(string strName) { string result=string.Empty ; if (string.IsNullOrWhiteSpace(s ...

  9. <textarea>输入框提示文字

    背景 看了过时的资料,花费大把时间,不过也有收获,还是写写吧! 分析 有同学可能想到直接在<textarea>标签内输入帮助文字,但是这又有一个新问题--因为<textarea> ...

  10. Apache+PHP 配置随笔

    准备安装包 1:安装VC++ 2012(vcredist_x64,我这边服务器为64位) 2:Apache安装包,php安装包 安装后配置工作 1:安装Apache服务,配置环境变量 httpd -k ...