The structure of the body
- In the Swift standard library, the vast majority of exposed types are structures, while enumerations and classes are just a few: for example
Bool
,Int
,Double
,String
,Array
,Dicttionary
And other common types are structures.
struct Person { var name: String var age: Int var sex: String } var person = Person(name: 'Tom', age: 18, sex: 'male ')// Initializer automatically generated by the compiler for a structureCopy the code
- All structures have an initializer (initializer, initializer, constructor, constructor) automatically generated by the compiler. Called in the last line above, the initializer can be passed in to initialize all members (storing properties, Stored Property).
Initializer for a structure
The compiler may generate multiple initializers for a structure, depending on the situation. The purpose is to ensure that all members have initial values and that the code is safe.
Graph one:
Figure 2:
Figure 3:
There is no problem with this:
Or this:
Because var x: Int? var y: Int? By default, the declaration has an initial value of nil, so no errors are reported.
Custom initializers
But why did we get an error when we added a custom initializer to Point? This is because once we define our initializers when we define a structure, the compiler will not automatically generate any other initializers for us.
Peep into the nature of the initializer
The above two pieces of code are equivalent, the first uses the system-generated no-parameter initializer, and the second uses our custom no-parameter initializer.
If you want to explore the nature of initializers, you need to look at their assembly code:
The assembly code is as follows:
Custom initializer:
The assembly code is as follows:
For the above two programs, they call the no-parameter initializer function is exactly the same at the bottom, assembly code even the number of lines is the same, so the judgment is equivalent. Syntax candy may be deceiving, but assembly never will.
Structures exist within structures
struct Point { var x: Int = 10 var y: Int = 50 var origin: Bool = true } var point = Point() print(MemoryLayout<Point>.size) print(MemoryLayout<Point>.stride) print(MemoryLayout<Point>.alignment) print(Mems.memStr(ofVal: & point)) / / output structure in vivo deposit in data = = = = = = = = = = = = = = = run results = = = = = = = = = = = = = = = 17 24 x0000000000000032 x000000000000000a 8 0 0 0x00007f95e1e07d01Copy the code
It can be seen from the above that the structure of Swift is the same as the structure of C language, and the member variable memory is close together.
class
The definition of a class is similar to that of a structure, but the compiler does not automatically generate initializers for classes that can pass in member values
When each member of a class has a default value, a no-argument initializer is created for it:
Var x: Int? It’s optional, so it automatically gets a default value of nil. In contrast to structs, classes are declared almost exactly like structs and can also add methods internally. On the surface, only the initializer looks a little different.
Class initializer
The initialization of the member is done in this initializer, and the proof method is the same as the assembly proof in the Struct above, which is not verbose here.
The difference between structures and classes
Structs are value types (enumerations are also value types) and classes are reference types (pointer types)
class Size {
var width = 1
var height = 2
}
struct Point {
var x = 3
var y = 4
}
func test() {
var size = Size()
var point = Point()
}
Copy the code
The size and point distribution in memory in the above code is as follows:
Object heap space application process
The assembly debugging page is displayed
In Swift, to create an instance object of class, to allocate memory to the heap space, the process is as follows:
-
Class.__allocating_init()
-
libswiftCore.dylib:
_swift_allocObject_
-
libswiftCore.dylib:
swift_slowAlloc
-
libsystem_malloc.dylib:
malloc
On Mac and iOS, the malloc function always allocates a multiple of 16 memory size, using class_getInstanceSize to get the actual memory size of the class object:
Value types
- Value type assigned to
var
,let
Or you can pass a parameter to a function, which makes a copy of everything, similar to a filecopy
,paste
Operation produces a brand new copy of the file. Deep copy
The assignment operation of a value type
-
In swift standard library, in order to improve the performance, String, Array, Dictionary, Set adopt Copy On Write technology
- For example, a copy operation is performed only when there is a write operation
- Swift ensures optimal performance for assignment operations of library value types, so there is no need to avoid assignment in order to ensure optimal freshness
Note that this is for the Swift standard library only. Swift does not use Copy On Write for custom constructs
-
Suggestion: If you do not need to modify it, try to define it as let
Var s1 = "Tom" var s2 = s1 s2. Append ("_Rose") print(s1)//Tom print(s2)//Tom_Rose var a1 = [1,2,3] var a2 = a1 A2. Append (4) a1 [0] = 2 print (a1) / / print (a2) [1 4] / / [1, 2, 3, 4] var d1 = [" Max ": 10, "min":2] var d2 = d1 d1["other"] = 7 d2["max"] = 12 print(d1)//["other": 7, "max": 10, "min":2] print(d2)//["max": 12, "min":2]Copy the code
Reference types
-
Assigning a reference to a var, let, or function is analogous to making a copy of the memory address (shortcut, link) to the same file. Shallow copy
class Size { var width: Int var height: Int init(width: Int, height: Int) { self.width = width self.height = height } } func test() { var s1 = Size(width: 10, height: 20) var s2 = s1 s2.width = 11 s2.height = 22 } test() Copy the code
An assignment operation of a reference type
class Size {
var width: Int
var height: Int
init(width: Int, height: Int) {
self.width = width
self.height = height
}
}
var s1 = Size(width: 10, height: 20)
s1 = Size(width: 11, height: 12)
Copy the code
Value type, reference type let
To summarize, let means that the contents of the memory space corresponding to the constant it modifies cannot be modified. Value types due to all the members in its memory, so is the let decorate, its internal members are not can modify the reference type because of its stored in the memory is just a pointer, so only the pointer value cannot be modified, but the pointer points to the object instance heap space, not a reference type memory what’s inside, Therefore, after being modified by let, you can still modify the values of the members of the heap space object.