“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
  • useextensionTo expand the function
  • Follow a protocol to provide a function

Difference:

  • classThere are inherited characteristics, andThe structure of the bodyUnable to inherit;
  • Type conversions can be performed inThe runtimeCheck and explainThe class instanceThe type of;
  • Class hasThe destructorTo release its allocated resources;deinit
  • Reference countingAllow for aThe class instanceThere 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 addressNext,High addressIn the;
  • MachOFile from aA virtual addressAt 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 areaand_text instruction area; (The global area,The constant areaand_text instruction areaAlso known collectively asThe global area);
  • The stack areaStretching from theHigh addresstoLower addressStretching;The heap areafromLower addresstoHigh addressStretching; whenThe stack areawithThe heap areaOverlap will occurStack overflow;
  • The stack areaDeposit:A local variableandContext in which a function is running;
  • The heap area: Store allobject;
  • The global area:GlobalstoreThe 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/globalData;
  • DATA.const: uninitialized constants;
  • DATA.bss: uninitializedStatic/localVariables;
  • 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 bodyMemory space inThe stackOn;
  • ageAt the low address,nameAt high address;

Class memory distribution

Struct (Struct); Struct (Struct);

  • classMemory space inThe heapOn;
  • ageAt the low address,nameAt 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 sMemory address inThe stack area
  • In structureClass pThe 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;