IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Swift 【Class】【struct】 -> 正文阅读

[移动开发]Swift 【Class】【struct】

1.定义

在Swift标准库中,绝大多数的公开类型都是结构体,而枚举和类只占很小一部分
比如Bool、Int、Double、 String、 Array、Dictionary等常见类型都是结构体

所有的结构体都有一个编译器自动生成的初始化器( initializer ,初始化方法、构造器、构造方法)

SwiftObject

在swift中,如果没有明确声明父类的类,则会隐式地继承自?SwiftObject?(支持与?Objective-C?混编的前提下,因为?SwiftObject?是一个?Objective-C?类),隐式继承来源于?swift?的?ABI/TypeLayout.rst?文档。

SwiftObject?的声明是?SWIFT_OBJC_INTEROP?为?true?的情况下才有声明的,而在苹果平台下,都是支持?swift?与?Objective-C?进行混编的,因此?SWIFT_OBJC_INTEROP?为?1(true)SWIFT_OBJC_INTEROP?宏的定义可在?Config.h?中找到

从?SwiftObject?的定义中可以看到

  • 第一个成员变量和?Objective-C?一样是?isa?指针,暂时猜想和?Objective-C?中的?isa?指针功能一样
  • 第二个成员变量是一个?SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS?宏,其定义可在?HeapObject.h?和?RefCount.h中找到,从命名上看是引用计数器

2.区别

2.1.类是引用类型,结构体是值类型。

值类型在传递和赋值时将进行复制,而引用类型则只会使用引用对象的一个指向。引用类型是在堆上,而值类型是在栈上进行存储和操作。相比栈上的操作,对上的操作更加复杂耗时,所以苹果官方推荐使用结构体,这样可以提高App运行的效率。值类型赋值给let var 或者函数传参的时候全是深拷贝;引用类型赋值给let var 或者函数传参的时候完,是将内存地址拷贝一份,属于浅拷贝。结构体属于值类型,标准库中的结构体采用copy on write策略,优化效率;

2.2.class有这几个功能struct没有的:

class可以继承,这样子类可以使用父类的特性和方法。
类型转换可以在runtime的时候检查和解释一个实例的类型。
可以用deinit来释放资源。
一个类可以被多次引用。


2.3.结构体不可以继承,可以继承;

2.4.结构体初始化的时候必须要给属性赋值,来决定结构体在内存中的布局.Class初始化的时候可以暂时不用赋值;


2.5.都可以实现方法,都可以添加计算属性和存储属性,都支持属性监听,都支持扩展.都可以遵守协议;


2.6.required关键字只支持Class, Class可以用static和Class 关键字修饰静态方法;Struct 只能用Static 修饰;

2.7,类一定是分配在堆空间上,结构体可能分配在堆空间:比如类中的结构体属性,栈空间:比如声明在方法中,数据段:声明为全局变量

2.8类,有析构函数。结构体不能有析构函数。

2.9.结构体构造函数会自动生成带参数的构造器。类不会对有初始化赋值生成带参数的构造器。

2.10.类有继承特性,结构体没有继承特性。结构体无继承特性,则无法对成员属性、成员方法、类属性、类方法进行重载。结构体的函数操作符需要static,不能使用class。

2.11.类中的每一个成员变量都必须被初始化,否则编译器会报错。而结构体不需要,编译器会自动帮我们生成init函数,给变量赋一个默认值。

2.12.类中可以有单例,结构体不能有

2.13NSUserDefaults:结构体不能序列化成NSDate,无法归档。类可以

2.14.混合开发时,oc中不能调用swift中的结构体

2.15.方法派发:

? 静态派发:编译器讲函数地址直接编码在汇编中,调用的时候根据地址直接跳转到实现,编译器可以进行内联等优化,Struct都是静态派发。

?动态派发:运行时查找函数表,找到后再跳转到实现,动态派发仅仅多一个查表环节并不是他慢的原因,真正的原因是它阻止了编译器可以进行的内联等优化手段

2.16.struct在func里面需要修改property的时候需要加上mutating关键字,而class就不用。

3.相同点

3.1定义存储值的属性
3.2定义方法
3.3定义下标以使用下标语法提供对其值的访问
3.4定义初始化器
3.5使用 extension 来拓展功能
3.6遵循协议来提供某种功能

3.7.范型

3.8协议采纳

4.观察器

4.结构体的内存结构

struct Point {
    var x: Int = 0
    var y: Int = 0
}

print(MemoryLayout<Point>.size)   // 16
print(MemoryLayout<Point>.stride) // 16
print(MemoryLayout<Point>.alignment) // 8

通过打印可知结构体Point实际占用16字节,总占用16字节,内存对齐为8字节。
这很好理解,因为两个存储属性x和y都是Int类型,都是占用8字节,所以实际占用16字节。

struct Point {
    var x: Int = 0
    var y: Int = 0
    var b: Bool = true
}

print(MemoryLayout<Point>.size)   // 17
print(MemoryLayout<Point>.stride) // 24
print(MemoryLayout<Point>.alignment) // 8

这里Point实际占用17字节,因为存储属性x是Int型占用8字节,y是Int型占用8字节,b是Bool型占用1字节。
内存对齐为8字节,所以总占用是8+8+8=24字节。

5.如何选择

5.1、 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些。

5.2、 结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。

5.3、 在表现抽象和多级别的对象层次时,类是最好的选择。

5.4、 大多数情况下该类型只是一些数据时,结构时最佳的选择。

5.5、结构体的主要目的是为了封装一些相关的简单数据值。

5.6、当你在赋予或者传递结构实例时,有理由需要封装的数据值被拷贝而不是引用。

5.7、任何存储在结构体中的属性是值类型,也将被拷贝而不是被引用。

5.8、结构体不需要从一个已存在类型继承属性或者行为。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:40:09  更:2022-07-21 21:40:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:47:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码