Swift 中的存储属性、计算属性以及属性观察器

Swift开发——存储属性与计算属性 Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结构体外部定义的变量和常量;②从面向对象程序设计的角度,结构体对应着现实世界的一个客观物体,描述这个物体的性质需要用到它的属性和方法; 阅读详情

1、存储属性

存储属性是一个作为特定类和结构体实例一部分的常量或变 量。存储属性要么是变量存储属性(由 var 关键字引入)要么是常量存储属性(由 let 关键字引入)
1> 常量结构体实例的存储属性:

  • 如果创建了一个结构体的实例并且把这个实例赋给常量,不能修改这个实例的属性,即使是声明为变量的属性
struct Person {
    var name: String
    var age: Int
}
//必须要声明一个变量类型的结构体实例,否则不能修改实例的属性.即使这个属性声明的是变量
var p = Person(name: "zhangsan", age: 12)
let s = p
p.age = 21
print("age is \(p.age)")

2> 延迟存储属性

  • 延迟存储属性的初始值在其第一次使用时才进行计算。可以通过在其声明前标注 lazy 修 饰语来表示一个延迟存储属性。
  • 如果被标记为 lazy 修饰符的属性同时被多个线程访问并且属性还没有被初始化,则无法保 证属性只初始化一次。
//延迟存储属性
class DataImporter {
    var fileName = "data.text"
    init() {
        print("dataImporter init")
    }
}
class DataManager {
    //声明一个延迟存储属性 importer
    lazy var importer = DataImporter()
    var data = [String]()
}

let manager = DataManager()
manager.data.append("some data")
manager.data.append("some more data")
print("manager.data.appended finish")
print(manager.importer.fileName) //第一次使用时才进行计算
/**
 manager.data.appended finish
 dataImporter init
 data.text
 */

2、计算属性

  • 除了存储属性,类、结构体和枚举也能够定义计算属性,而它实际并不存储值。相反,它提供一个读取器和一个可选的设置器来间接得到和设置其它的属性和值。
    1> 只读计算属性:
  • 一个有读取器但是没有设置器的计算属性就是所谓的只读计算属性。只读计算属性返回一个值,也可以通过点语法访问,但是不能被修改为另一个值
  • 必须用 var 关键字定义计算属性(包括只读计算属性)为变量属性,因为它们的值不是固定的。 let 关键字只用于常量属性,用于明确那些值一旦作为实例初始化就不能更改

3、属性观察者

  • willSet 会在该值被存储之前被调用
  • didSet 会在一个新值被存储后被调用
  • 如果你实现了一个 willSet 观察者,新的属性值会以常量形式参数传递。你可以在你的 willSet 实现中为这个参数定义名字。如果你没有为它命名,那么它会使用默认的名 newValue
  • 如果你实现了一个 didSet观察者,一个包含旧属性值的常量形式参数将会被传递。你可以为 它命名,也可以使用默认的形式参数名 oldValue 。如果你在属性自己的 didSet 观察者里给 自己赋值,你赋值的新值就会取代刚刚设置的值
class StepCounter {
    var totalStep: Int = 0 {
        willSet(newTotalSteps) {  //为新的属性值定义名字: newTotalSteps, 如果没有定义,默认就是 newValue
            print("newtotalSteps: \(newTotalSteps)")
        }
        didSet {  //默认的属性名是 oldValue
            if totalStep > oldValue {
                print("Add \(totalStep - oldValue) steps")
            }
        }
    }
}
var stepCounter = StepCounter()
stepCounter.totalStep = 200
stepCounter.totalStep = 360
stepCounter.totalStep = 896
/**
 newtotalSteps: 200
 Add 200 steps
 newtotalSteps: 360
 Add 160 steps
 newtotalSteps: 896
 Add 536 steps
 */
  • 观察属性的能力同样对全局变量和局部变量有效。全局变量是定义在任何函数、方法、闭包或者类型环境之外的变量。局部变量是定义在函数、方法或者闭包环境之中的变量
//定义一个全局变量
var count: Int = 0 {
    willSet(newCount) {
        print("newCount: \(newCount)")
    }
    didSet {
        print("Add count: \(count - oldValue)")
    }
}
count = 10
if count == 10 {
    print("ten")
}

4、类型属性

  • 使用 static 关键字来定义类型属性,用类名来调用类型属性。对于类类型的计算类型属性,你可以使用 class 关键字 来允许子类重写父类的实现
class SomeClass {
    static let count = 10  //定义存储型类型属性
    static var count2: Int {   //定义计算型类型属性
        return 20
    }
    class var count3: Int { //使用 class 关键字允许子类重写父类的实现
        return 30
    }
}
//直接使用类型调用即可
print("\(SomeClass.count)")

5、实例方法

  • 实例方法是属于特定类实例、结构体实例或者枚举实例的函数
  • 每一个类的实例都隐含一个叫做 self 的属性,它完完全全与实例本身相等
  • 一般不需要在代码中显式地写出 self
  • 当一个实例方法的形式参数名与实例中某个属性拥有相同的名字的时候,可以使用 self 属性来区分形式参数名和属性名

1> 在实例方法中修改属性

  • 结构体和枚举是值类型。默认情况下,值类型属性不能被自身的实例方法修改
  • 在 func 关键字前放一个 mutating 关键字来指定可以修改属性
  • 通过在 func关键字之前使用 static关键字来明确一个类型方法。类同样可以使用 class关键 字来允许子类重写父类对类型方法的实现
  • 枚举的异变方法可以设置隐含的 self 属性为相同枚举里的不同成员
struct Point {
    var x = 0
    var y = 0

    //使用 mutating 改变 x 和 y 的值
    mutating func moveBy(x: Int, y: Int){
        self.x += x
        self.y += y
    }

    //使用 mutating 改变 self 的值
    mutating func moveBy2(x: Int, y: Int) {
        self = Point(x: self.x + x, y: self.y + y)
    }

    func printInfo() {
        print("x is \(x), y is \(y)")
    }
    //添加 static 关键字,就是类方法
    static func info() {
        print("类方法")
    }
}
var point = Point(x: 2, y: 3)
//point.moveBy(x: 3, y: 5)
point.moveBy2(x: 3, y: 5)
point.printInfo()
Point.info()
//枚举的异变方法
enum Direction {
    case north, south, east, west
    mutating func next() {
        switch self {
        case .north:
           self = .south
        case .south:
            self = .north
        case .east:
            self = .west
        case .west:
            self = .east
        }
    }
}
var dir = Direction.south
dir.next()

6、下标

  • 类、结构体和枚举可以定义下标,它可以作为访问集合、列表或序列成员元素的快捷方式。可使用下标通过索引值来设置或检索值而不需要为设置和检索分别使用实例方法
  • 可以为一个类型定义多个下标,并且下标会基于传入的索引值的类型选择合适的下标重载使用。下标没有限制单个维度,可以使用多个输入形参来定义下标以满足自定义类型的需求
  • 下标脚本允许你通过在实例名后面的方括号内写一个或多个值对该类的实例进行查询。它的语法类似于实例方法和计算属性。使用关键字 subscript 来定义下标,并且指定一个或多个 输入形式参数和返回类型,与实例方法一样。与实例方法不同的是,下标可以是读写也可以 是只读的
  • 在对应类型的实例上调用下标,同样也可以定义类型本身的下标,这类下标叫做类型下标。可通过在 subscript 关键字前加 static 关键字来标记类型下标。在类里则使用 class 关键字,这样可以允许子类重写父类的下标实现
//下表语法
struct TimesTable {
    let multipier: Int
    subscript(index: Int) -> Int {
        return multipier * index
    }
}
let threeTimesTable = TimesTable(multipier: 3)
print("six time three is \(threeTimesTable[6])")  //18
Swift5中的存储属性和计算属性以及属性观察器 Swift 属性将值跟特定的类、结构或枚举关联。 属性可分为存储属性和计算属性: 存储属性 计算属性 存储常量或变量作为实例的一部分 计算(而不是存储)一个值 用于类和结构体 用于类、结构体和枚举 存储属性和计算属性通常用于特定类型的实例。 属性也可以直接用于类型本身,这种属性称为类型属性。 另外,还可以定义属性观察器来监控属性值的变化,以此来触发一个自定义的操作。属性观察器可以添加到自己写的存储属性上,也可以添加到从父类继承的属性上。 一、存储属性 简单来说,一个存储属性就是存. 阅读详情

相关推荐

双摄像头的实时视频拼接及目标跟踪(一)

本章主要讲图像拼接算法的研究 先膜拜一下知乎大佬全面的叙述:https://www.zhihu.com/question/34535199/answer/135169187 本文图像拼接是基于opencv的图像拼接,流程分为以下几步 ...

Y.W.jian的博客 3万+

Swift 之存储属性和计算属性

参考资料 https://www.jianshu.com/p/07b7cb4ef603

qq_39438055的博客 1046

稳定性性能系列之五——Native Crash深度分析:工具实战

深入理解Native Crash的机制与分析方法,掌握addr2line、ndk-stack、gdb等核心工具的实战使用,学会从Tombstone文件中快速定位问题根因

Cheson的专栏 1547

Swift 属性

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

xiaoxiaobukuang的专栏 1607

整理的15个公开且可直接使用的电力视觉输电线路领域数据集

而巡检数据是目前来说影响我们做科研的最大阻碍,为此本内容主要总结了,现有的且公开免费的巡检数据集,供大家使用。STN PLAD数据集133个航拍图像,五个电力部件:电力塔及其塔的ID、绝缘子,防震锤,联板(yoke),图像的尺寸在5472×3648到5472×3078。IDID数据集:2000张图像,包含三个类别,正常绝缘子,破损绝缘子和闪络绝缘子三个类别,用于目标检测的实验。TTPLA数据集,用于实例分割,1100张尺寸为3840×2160,包含两个类别,电力杆塔和电力线。主要用于电力杆塔的目标检测。

weixin_42048361的博客 5017

C++五子棋人机对战

使用C++,开发五子棋人机对战,快速提升C++项目开发能力。

程序员Rock的博客 5万+

2、Swift存储属性、属性观察者、延迟属性、类型属性

一、存储属性 1、创建一个类并声明两个变量、而这两个变量皆为存储属性: 由篇1得:8字节为metadata、8字节为refCounts;age占用8字节、age2占用8字节、当前对象 t 地址输出可得当前变量存储值 0x0000000000000012 --> 18 0x000000000000001c --> 28 2、属性误区:不可在set方法中调用自身、否则会造成递归调用、程序崩溃 计算属性不占用内存空间 通过分析SIL文件我们查看下计算属性的本质 class S.

Holothurian 1106

从DIY到实战:手把手教你搭建一个媲美吉时利2450的nA级电流源表(附原理图与避坑指南)

本文详细解析如何从零打造nA级精密电流源,涵盖核心设计原理、PCB布局技巧、热电偶效应应对及校准验证体系。通过低成本替代方案和优化设计,实现媲美商用源表的性能,特别适合硬件爱好者和独立开发者。文章还提供原理图与避坑指南,助你轻松搭建高精度电流源系统。

weixin_42656416的博客 292

Swift 属性观察器

作者:Mattt,原文链接,原文日期:2018-08-20 译者:Hale;校对:numbbbbb,pmst,Yousanflics;定稿:Forelax 到了 20 世纪 30 年代,Rube Goldberg 已成为家喻户晓的名字,与 “自营餐巾” 等漫画中描绘的奇异复杂和异想天开的发明同义。大约在同一时期,阿尔伯特·爱因斯坦对尼尔斯·玻尔量子力学的普遍解释进行了 批判,并从中提出了“鬼...

weixin_34224941的博客 586

【邻接表存图模板】vector邻接表、数组邻接表、链式前向星

一、目录 一、目录 二、前言 三、邻接表“详解” (一)边的信息 (二)几种邻接表的实现方法“详解” 1.数组邻接表 代码 2.vector邻接表 代码 vector邻接表还有一种魔性写法: 3.链式前向星 代码 四、总结 二、前言 本来之前自己太弱了,一直只会用邻接矩阵,后来发现邻接表才是主流... 参考&特别鸣谢: https://www.cnblog...

十里寒塘路♣烟花一半醒 3113

为什么 ADT 在 SAP BTP ABAP environment 里认证成功却无法登录 Service Instance:根因拆解与一站式修复路线

摘要 ADT报错"认证成功但Service Instance登录失败"通常源于ABAP租户的权限或用户映射问题,而非账号密码错误。常见原因包括:1) ABAP租户内未创建对应业务用户;2) 业务用户缺少开发角色(如SAP_BR_DEVELOPER);3) BTP角色集合未分配或IdP组映射缺失;4) 浏览器会话混淆身份;5) 连接了非开发租户(如Customizing Tenant);6) 实例休眠导致误判。 解决方法:检查ABAP业务用户及角色分配,确认BTP角色集合映射,使用隐身窗口

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 254

Swift 中的计算属性、懒存储属性、属性观察器

计算属性 Swift 中的计算属性不存储值 而是提供一个getter 和 setter 来分别进行获取值 和 设置其他属性的值 , getter 使用 get 关键字, setter 使用 set关键字进行定义。 如果计算属性的 setter方法没有将被设置的值定义一个名称,会默认使用 newValue 名称代替 代码示例class person : NSObject { var len

骑着蜗牛赛跑的博客 1062

SAP-ABAP:字符与数值类型转换详细指南

SAP-ABAP:字符与数值类型转换详细指南

baidu_35680696的博客 1480

Swift系列九 - 属性

任何一门语言都有属性的概念。Swift中的属性是怎么的呢? 一、属性 Swift中跟实例相关的属性可以分为2大类:存储属性和计算属性。 1.1. 存储属性(Stored Property) 特点: 类似于成员变量的概念; 存储在实例的内存中; 结构体、类可以定义存储属性; 枚举不可以定义存储属性。 示例代码: struct Circle { var radius: Double } class classCircle { var radius: Double } 关于存储属性,Sw

1024星球 419

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

swift基础语法(23- 属性,存储属性,延迟存储属性,计算属性,属性观察器,类属性)

存储属性 Swift中的存储属性就是以前学习OC中的普通属性 在结构体或者类中定义的属性, 默认就是存储属性 struct Person { var name: String var age: Int } var p:Person = Person(name: "qbs", age: 30) p.name = "jor" p.age = 50 常...

abc48765的博客 131

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Swift之属性的使用和实例展示

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

╰つ栺尖篴夢ゞ 3万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

学习Swift--属性

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

123

Swift-属性,存储属性(var、let)、计算属性(getter、setter)、属性观察器、全局变量和局部变量

1. 存储属性 一个存储属性就是存储在特定类或结构体实例里的一个常量或变量。 可以是变量存储属性(用关键字 var 定义)。 也可以是常量存储属性(用关键字 let 定义)。 struct FixedLengthRange { var firstValue: Int let length: Int } var rangeOfThreeItems = FixedL...

DevXue的博客 704

iOS开发之Swift篇(9)—— 属性

目录版本存储属性延迟加载存储属性计算属性只读计算属性属性观察器类型属性 版本 Xcode 11.3.1 Swift 5.1.3 属性将值与特定的类、结构体或枚举关联。 存储属性会将常量和变量存储为实例的一部分 计算属性则是直接计算(而不是存储)值 属性可以直接与类型本身关联,这种属性称为类型属性。 存储属性 struct Range { var min = 0.0 var ma...

看影成痴 480

iOS Swift No.10 - 属性 1

结构体,类和枚举中与值相关联的东西就叫做该结构体,类或枚举的属性,属性一般都是该结构体,类或枚举的常量或/和变量。属性又可以分为存储属性和计算属性。存储属性可以由结构体和类提供,存储属性其实就是存储常量或变量作为实例的一部分。而计算属性可以由结构体,类和枚举提供。计算属性并不是用来存储属性的,而是用来提供一个getter和一个可选的 setter?来间接获取或重新设置其他属性或值。

Hello Swift ! 254

Swift项目中的存储属性和计算属性详解

Swift项目中的存储属性和计算属性详解 【免费下载链接】swift The Swift Programming Language 项目地址: https://gitcode.com/GitHub_Trending/swi/swi...

gitblog_00903的博客 433

Swift - 关于属性(Property)

1、Swift中类可以使用计算属性,即使用get和set来间接获取/改变其他属性的值 class Calumator{ var x:Int = 5; var y:Int = 6; var sum:Int{ get{ return x + y } set(val)...

cym_bj 982

swift之属性与单例模式

swift之属性与单例模式一、属性1.1-swift中的属性1.2-存储属性1.3-计算属性1.4-枚举rawValue原理1.5-延迟存储属性1.6-属性观察器1.7-全局变量局部变量1.8-inout详解1.9-类型属性二、单例模式 一、属性 1.1-swift中的属性 /* 存储属性 类似于成员属性的概念 存储在实例的内存中 结构体、类可以定义存储属性 枚举不可定义存储属性 计算属性 本质就是方法(函数) 不占用实例的内存 */ struct Test { var value:Dou

岁月如歌 475

Swift学习笔记 (十九) 属性

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

sjl51060的专栏 234

Swift之属性

Swift 属性 存储属性 存储常量或者变量的 要么给它默认值,要么在构造方法里初始化 简单来说,一个存储属性就是存储在特定类或结构体的实例里的一个常量或变量。 存储属性可以是变量存储属性(用关键字var定义),也可以是常量存储属性(用关键字let定义)。 可以在定义存储属性的时候指定默认值 也可以在构造过程中设置或修改存储属性的值,甚至修改常量存储属性的值 计算属性 计算属性不直接存储值 访问时...

m0_46311757的博客 276

Swift --- 属性(property)和输入输出参数(inout)

Swift中跟实例相关的属性可分为两大类 存储属性: 类似于成员变量这个概念 存储在实力的内存中 结构体、类可以定义存储属性 枚举不可以定义存储属性 计算属性 本质就是方法(函数) 不占用实力的内存 枚举、结构体、类都可以定义计算属性 struct Circel { // 存储属性 var radius: Double // 计算属性 var dia...

宋卓的博客 1148
上一篇: Swift 中枚举的基本用法
下一篇: Swift 类、结构体的初始化
same_life
博客等级 码龄7年 25粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值