“This is the ninth day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Class is the core of object-oriented programming. In object-oriented programming, everything is an object, and class is a way to describe the object. In Object-C, a structure can only define attributes, not methods. In Swift, structures are very powerful and can encapsulate attributes and methods. In some cases, structs can be used instead of classes;
Some advanced features of the class are not available in the structure, and need to be selected according to the actual situation.
Introduction to classes and structures
Let’s start with the following code:
In the code above, we create a Teacher class with two attributes age and name, and create an initializer init(age: Int, name: String);
Next, we directly change the class keyword to struct:
At this point, Teacher changes from a class to a structure, and can still be compiled, indicating that to some extent, the class and the structure are similar;
Similarities and differences between classes and structures
Similarities:
- Define properties that store values;
age
name
- Define method;
func
- Defines subscripts that provide access to their values using subscript syntax;
subscript
- Define initializers;
init
- use
extension
To expand the function - Follow a protocol to provide a function
Difference:
class
There are inherited characteristics, andThe structure of the body
Unable to inherit;- Type conversions can be performed in
The runtime
Check and explainThe class instance
The type of; - Class has
The destructor
To release its allocated resources;deinit
Reference counting
Allow for aThe class instance
There are multiple references;
Reference type and value type
The first thing to note when using classes and structures is:
A class is a reference type. The variables of a class do not store the specific instance object directly, but refer to the memory address of the specific instance. Structs are value types
Reference types
As shown in the code above: we create a T to receive an instance object of class Teacher, but T does not store the instance object of class Teacher directly. Instead, T stores a reference to the memory address of the Teacher instance object. Similarly, if we assign t to other variables, such as T1, then t and T1 store references to the memory address of Teacher instance variable.
**withUnsafePointer** we can check the memory address of t and T1 with **withUnsafePointer**. Note that t and T1 require var.
We see that t and T1 are located next to each other in memory, 8 bytes apart; **x/8g**
It can be seen that the 8 bytes of data stored on the memory address corresponding to T is ** 0x00000001072213A0 **, which exactly corresponds to the memory address of the Teacher instance object ** 0x1072213A0 **; That is to say, the 8-byte data difference between T and T1 stores the memory address corresponding to the brokenhearted object.
The difference between Po and p is that Po only outputs the corresponding value, while p returns the type of the value and a reference to the command result. X /8g: reads the value in memory (8G is output in 8-byte format);
Value types
Whereas reference variables store addresses, value types store concrete instances or concrete values.
As the code above shows: S and s1 are two different variables, but do they store the same thing? Let’s take a look through the Po execution:
You can see that age and name are stored in s and S1, not addresses; At this point, we modify the age property in s1 to see if the same changes occur in S:
When the data in S1 is modified, the data in S does not change, indicating that s and S1 store different data.
In general, reference types are stored on the heap and value types are stored on the stack;
The basic concept diagram of memory area is as follows:
- As shown in the figure:
Lower address
Next,High address
In the; MachO
File from aA virtual address
At first, only a few memory addresses are available for us to manipulate;- The operable memory area is divided into:
The stack area
,The heap area
,The global area
,The constant area
and_text instruction area
; (The global area
,The constant area
and_text instruction area
Also known collectively asThe global area
); The stack area
Stretching from theHigh address
toLower address
Stretching;The heap area
fromLower address
toHigh address
Stretching; whenThe stack area
withThe heap area
Overlap will occurStack overflow
;The stack area
Deposit:A local variable
andContext in which a function is running
;The heap area
: Store allobject
;The global area
:Global
storeThe global variable
.constant
.Code section
;
So how do you check whether the memory address is on the stack or the heap? Here’s a tool that prints out memory addresses for us;
As in the above code, we can analyze it by cat address instruction. The local variable age is stored in the stack.
In our MachO file we have multiple segments, each with a different function; Each Section is divided into several smaller sections:
TEXT.text
: machine code;TEXT.cstring
: hardcoded string;TEXT.const
: initializedconstant
;DATA.data
: initialized mutableStatic/global
Data;DATA.const
: uninitialized constants;DATA.bss
: uninitializedStatic/local
Variables;DATA.common
: uninitialized symbol declaration;
As the code above, according to the printed result: A is the initialized global Data, stored in data.data; Age is not initialized yet, stored in Data.common;
Memory distribution of classes and structures
You can use the frame variable-l directive to view the memory distribution
The memory distribution of the structure
The structure of the body
Memory space inThe stack
On;age
At the low address,name
At high address;
Class memory distribution
Struct (Struct); Struct (Struct);
class
Memory space inThe heap
On;age
At the low address,name
At high address;
Memory allocation process:
Allocate 8 bytes of memory on the stack for s; During Student initialization, find the appropriate memory region on the heap, return the address of the memory region, and copy the values of age and name to the memory space of the heap. Finally, I’m going to point the memory address on the stack to the heap;
Memory distribution when classes and structs are mixed
Structure s
Memory address inThe stack area
- In structure
Class p
The memory address of theThe heap area
;
There is a time and speed difference between heap and stack reallocation of memory. We can analyze this by StructVsClassPerformance project on GitHub;
When selecting data structure type, structure should be preferred as far as possible. The structure is on the stack, thread-safe; In memory allocation, the stack area is also faster than the heap area;