Value types and reference types in Swift are distinguished and used

  • 2020-05-10 22:59:21
  • OfStack

There are two types in Swift:

● value type (Value Types) : each instance retains a unique copy of the data, usually in the form of a struct (struct), enumeration (enum), or tuple (tuple).
● reference type (Reference Type) : each instance shares the same data source, usually in the form of a class (class).

In this post, we'll talk about the benefits of each type and how to use it.

The difference between a value type and a reference type

Value types and reference types are the most basic results after replication, respectively. When a value type is copied, it is equivalent to creating a completely independent instance, which keeps its own unique data and will not be affected by the data changes of other instances:


    // The following is 1 Examples of value types
    struct S { var data: Int = -1 }
    var a = S()
    var b = a                           // b is a A copy of the
    a.data = 42                         // To change the a The data, b Is not affected
    println("\(a.data), \(b.data)")     // The output "42, -1"

The value type is like id card copy 1 kind, after copying out, modify the original above the content, the content on the copy will not change.

On the other hand, when copying a reference type, you are actually silently creating a Shared instance clone, which shares a set of data. So modifying the data for any one of these instances will affect the other one as well.


    // The following is 1 Examples of reference types
    class C { var data: Int = -1 }
    var x = C()
    var y = x                           // y is x A copy of the
    x.data = 42                         // To change the x Is equal to at the same time modified y
    println("\(x.data), \(y.data)")     // The output "42, 42"

The role of Mutation (modification) in security

Value types, rather than reference types, make it easier to sort things out in a lot of code. If you always get a single copy of an instance, you can rest assured that it will not be silently modified by the rest of your app code. This is especially important in a multithreaded environment, where another thread may be secretly modifying your data. This can cause serious program errors, which can be difficult to eliminate during debugging.

Since the difference is primarily the consequence of modifying the data, it makes no difference which type is used when the instance's data is read-only and there is no need to change it.

You might be thinking, sometimes I might need a class that's completely immutable. This makes it easier to use Cocoa NSObject objects while retaining the benefits of value semantics. Today, you can write an immutable class with Swift (immutable class) by using only immutable storage properties and API to avoid any state that can be modified. In fact, many basic Cocoa classes, such as NSURL, are designed as immutable classes. However, the Swift language currently only enforces the immutability of value types struct and enum, not reference types for classes. (for example, there is no support for forcing subclasses to be immutable)

How to select a type?

So when we want to create a new type, how do we decide whether to use a value type or a reference type? When you use the Cocoa framework, many API are used by subclasses of NSObject, so you must use the reference type class. In other cases, there are several guidelines:

When to use a value type:

● when the == operator is used to compare instance data
● when you want a copy of that instance to remain independent
● when data is used by multiple threads

When to use reference type (class) :

● when the == operator is used to compare instance identities
● you want to create a Shared, mutable object

In Swift, arrays (Array), strings (String), and dictionaries (Dictionary) are all value types. They are like the simple int values in C, which are 1 individual data unit. You don't have to do anything to prevent other code from secretly changing them. More importantly, you can safely pass variables between threads without needing to synchronize them. In the spirit of Swift's high security, this mode will help you write more controlled code with Swift.


Related articles: