//属性

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. poj1062昂贵的聘礼(Dijkstra**)

    /* 题意: 物主有一个物品,价值为P,地位为L, 以及一系列的替代品Ti和该替代品所对应的"优惠"Vi g[u][i] 表示的是u物品被i物品替换后的优惠价格!(u>0, ...

  2. JavaScript及兼容性笔记

    1. Json to String JSON.stringify(jsonobj)//(IE8+,Chrome 1+,FF 3+) //参考 http://www.nowamagic.net/libr ...

  3. Windows Azure Cloud Service (47) 修改Cloud Service时区

    <Windows Azure Platform 系列文章目录> 本文介绍内容适合于Azure Global和Azure China 我们在使用Cloud Service的时候,会发现默认的 ...

  4. Azure Backup (1) 将SQL Server 2012虚拟机中数据库备份到Azure Storage

    <Windows Azure Platform 系列文章目录> 本文介绍的是由国内世纪互联运维的China Azure,相比国外的Global Azure.主要区别是存储账号的DNS地址不 ...

  5. 10套免费的 Photoshop UI 元素以及 PSD 素材

    免费的 PSD 用户界面工具包以及可以编辑 Photoshop PSD 文件,有你需要的设计漂亮的用户界面和惊人使用体验.这些用户界面工具包可有免费下载,可随意定制的,而且这些 PSD 分层素材文件组 ...

  6. .NET 2.0 检测

    #include <stdio.h>#include <stdlib.h>#include<windows.h> char GetSystemDisk(){    ...

  7. Android系统如何录制屏幕(录制成mp4格式)

    不管是教学,还是为了演示,如果能将Android手机(或平板)的屏幕录制成视频文件,那是一件非常酷的事(iOS8已经提供了这一功能,能通过OS X直接在Mac上录制iPad.iPhone的屏幕,win ...

  8. [Asp.net 5] DependencyInjection项目代码分析2-Autofac

    Microsoft.Framework.DependencyInjection.Autofac源码分析 该工程只有一个代码静态类AutofacRegistration,但是该类有3个扩展方法,以及3个 ...

  9. js中的延迟执行和定时执行

    在js中,延迟执行函数有两种,setTimeout和setInterval,用法如下: function testFunction(){Console.log('hovertree.com');} s ...

  10. C#编程总结(十)字符转码

    C#编程总结(十)字符转码 为了适应某种特殊需要,字符需要根据规则进行转码,便于传输.展现以及其他操作等. 看看下面的转码,就知道他的用处了. 1.字符串转码 根据原编码格式与目标编码格式,完成转换. ...