swift内存管理:值类型与引用类型
Use struct to create a structure. Structures support many of the same behaviors as classes, including methods and initializers. One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference.
As per the apple documentation String is a Struct (value type) and NSString is Class (Reference type). Reference type means if we change the value of reference it will reflect in the original value too. check the below code.
Reference Types vs. Value Types
So, what’s the core difference between these two types? The quick and dirty explanation is that reference types share a single copy of their data while value types keep a unique copy of their data.
Swift represents a reference type as a class. This is similar to Objective-C, where everything that inherits from NSObject is stored as a reference type.
There are many kinds of value types in Swift, such as struct, enum, and tuples. You might not realize that Objective-C also uses value types in number literals like NSInteger or even C structures like CGPoint.
To better understand the difference between the two, it’s best to start out with what you may recognize from Objective-C: reference types.
https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
Value and Reference Types
Types in Swift fall into one of two categories: first, “value types”, where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple. The second, “reference types”, where instances share a single copy of the data, and the type is usually defined as a class. In this post we explore the merits of value and reference types, and how to choose between them.
What’s the Difference?
The most basic distinguishing feature of a value type is that copying — the effect of assignment, initialization, and argument passing — creates an independent instance with its own unique copy of its data:
// Value type example
struct S { var data: Int = -1 }
var a = S()
var b = a // a is copied to b
a.data = 42 // Changes a, not b
println("\(a.data), \(b.data)") // prints "42, -1"
Copying a reference, on the other hand, implicitly creates a shared instance. After a copy, two variables then refer to a single instance of the data, so modifying data in the second variable also affects the original, e.g.:
// Reference type example
class C { var data: Int = -1 }
var x = C()
var y = x // x is copied to y
x.data = 42 // changes the instance referred to by x (and y)
println("\(x.data), \(y.data)") // prints "42, 42"
The Role of Mutation in Safety
One of the primary reasons to choose value types over reference types is the ability to more easily reason about your code. If you always get a unique, copied instance, you can trust that no other part of your app is changing the data under the covers. This is especially helpful in multi-threaded environments where a different thread could alter your data out from under you. This can create nasty bugs that are extremely hard to debug.
Because the difference is defined in terms of what happens when you change data, there’s one case where value and reference types overlap: when instances have no writable data. In the absence of mutation, values and references act exactly the same way.
You may be thinking that it could be valuable, then, to have a case where a class is completely immutable. This would make it easier to use Cocoa NSObject objects, while maintaining the benefits of value semantics. Today, you can write an immutable class in Swift by using only immutable stored properties and avoiding exposing any APIs that can modify state. In fact, many common Cocoa classes, such as NSURL, are designed as immutable classes. However, Swift does not currently provide any language mechanism to enforce class immutability (e.g. on subclasses) the way it enforces immutability for struct and enum.
How to Choose?
So if you want to build a new type, how do you decide which kind to make? When you’re working with Cocoa, many APIs expect subclasses of NSObject, so you have to use a class. For the other cases, here are some guidelines:
Use a value type when:
- Comparing instance data with == makes sense
- You want copies to have independent state
- The data will be used in code across multiple threads
Use a reference type (e.g. use a class) when:
- Comparing instance identity with === makes sense
- You want to create shared, mutable state
In Swift, Array, String, and Dictionary are all value types. They behave much like a simple int value in C, acting as a unique instance of that data. You don’t need to do anything special — such as making an explicit copy — to prevent other code from modifying that data behind your back. Importantly, you can safely pass copies of values across threads without synchronization. In the spirit of improving safety, this model will help you write more predictable code in Swift.
https://developer.apple.com/swift/blog/?id=10
相关文章
- java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
- 操作系统内存管理,你能回答这 8 个问题吗?
- Oracle 自己主动内存管理 SGA、PGA 具体解释
- FMOD热更新在安卓下的堆内存占用
- Python的内存管理
- C#【必备技能篇】垃圾回收机制(GC)的理解(资源清理+内存管理)
- win11内存完整性打不开的解决方法
- c语言内存管理
- Linux系统如何查看内存
- Metasploit运行环境内存不要低于2GB
- ios block 内存管理时使用注意
- 《C程序设计新思维》一第6章 玩转指针6.1 自动、静态和手工内存
- 《DB2性能管理与实战》——2.2 共享内存与私有内存
- Objective-C内存管理教程和原理剖析(三)
- 内存映射
- JS高阶---数据、变量、内存
- 深入了解Java虚拟机和内存管理
- JAVA 内存管理总结
- objective-c启用ARC时的内存管理
- SQLServer因为OS虚拟内存不足而hang住异常解决-锁定内存页 (LPIM)
- 运维脚本 内存管理统计(5)
- jmap查看内存使用情况与生成heapdump--转
- 单片机的内存分配(变量的存储位置)详解
- Windows下C++软件调试——检测内存泄露
- linux的内存性能评估
- php unset()函数销毁变量但没有实现内存释放
- QT - 内存泄漏检测
- 内存管理[6]测试堆的内存占用情况
- 内存管理[3]堆
- 内存溢出定位工具:MAT