“This is the fourth day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

In Swift, classes are reference types and structures are value types. Value types are copied when passed and assigned, whereas reference types use only one reference to the reference object. Classes and structs and their differences:

The structure of the body

In the Swift standard library, most public types are structures, while enumerations and classes account for only a small part, such as Bool, Int, Double, String, Arrary, Dictionary, etc.

The construction method of the structure

All structures have an initializer (initalizer, initializer, constructor, constructor) automatically generated by the compiler, as in this example:

Depending on the situation, the compiler may generate multiple initializers for the structure. The purpose is to ensure that all members have initial values.

Custom initializers

struct Person {
    var name: String
    var age: Int = 20
    var sex: Bool?

    init(name: String) {
        self.name = name
    }
}

var person = Person(name: "candy")
Copy the code

If a member is nil and is of type var, no assignment is required during initialization

The memory structure of the structure

struct Person {
    var name: String
    var age: Int
    var sex: Bool
}

var person = Person(name: "candy", age: 20, sex: true)

// Align 8 bytes
print(MemoryLayout<Person>.alignment)
// Actually takes 25 bytes
print(MemoryLayout<Person>.size)
// The structure takes up 32 bytes, and since it is 8-byte aligned, Bool also allocates 8 bytes of space
print(MemoryLayout<Person>.stride)
Copy the code

class

The compiler does not automatically generate member initializers for classes, but provides default initializers for structures. When creating instances of classes and structures in Swift, you must set appropriate initial values for all storage properties, otherwise an error will be reported. You must provide a designated initializer for your class, or you can specify a portable initializer for your class.

Specifies an initializer

All attributes of the current class must be initialized before invoking the specified initializer call of the parent class

class Person {
    var age: Int
    var name: String
    
    init(_ age: Int._ name: String) {
        self.age = age
        self.name = name
    }
}
Copy the code

Convenient initializer

Using the convenience modifier, you must invoke another initializer of the same class before assigning a value to the property

convenience init(a){
    self.init(20."candy")}Copy the code

Initializers can fail

If something doesn’t meet, there’s an initialization failure, so return nil

init? (_ age: Int, _ name: String) { if (age < 20) { return nil } self.age = age self.name = name }Copy the code

Necessary initializer

Using the required modifier, represents the initializer that all subclasses of the class must implement

required init(_ age: Int, _ name: String) {
        self.age = age
        self.name = name
    }
Copy the code

The difference between classes and structures

Similarities:

  • Defines attributes that store values
  • Define initializers
  • Define subscripts to provide access to values using subscript syntax
  • Define methods
  • Use Extension to extend functionality
  • Follow a protocol to provide a function

The main differences are:

  • Classes have inheritance, structs do not
  • A class has a destructor that frees its allocated resources
  • Reference counting allows multiple references to a class instance
  • Conversions are types that you can examine and interpret class instances at run time

The difference between 1:

  • A class is a reference type: that is, a variable of class type stores a reference to the memory address of the instance object rather than the instance object of the class
  • Structs are value types: whereas reference types store addresses, value types store concrete instances
class Person {
    var age: Int
    var name: String
    required init(_ age: Int._ name: String) {
        self.age = age
        self.name = name
    }
}

func test(a){
    var person = Person(20."candy")
    var person1 = person
    print(class_getInstanceSize(Person.self))
}

test()
Copy the code

Run the project and print the following information:

WithUnsafePointer: The function outputs the corresponding memory address

struct Person {
    var age: Int
    var name: String
    init(_ age: Int._ name: String) {
        self.age = age
        self.name = name
    }
}

func test(a){
    var person = Person(20."candy")
    var person1 = person
    print("")
}
test()
Copy the code

Run the project and print the following information:

It can also be concluded from the actual printed information that the object instance prints the address pointing to memory on the heap, while the structure instance prints the content directly. You can also see that the reference type corresponds to a shallow copy and the structure corresponds to a deep copy.

The difference between 2:

Second, reference types and value types are stored in different locations in memory. Reference types are stored on the heap, and value types are stored on the stack

  • In iOS development, memory is mainly divided into heap area, stack area, global area, constant area, code area five areas

  • Stack area: storage program temporarily created variables, function parameters, local variables, created and released by the compiler;
  • Heap area: allocated and freed by programmers to store dynamically allocated memory segments during runtime, such as objects;
  • Global static area: The global area is the memory allocated at compile time to hold global variables.
  • Constant area: memory space allocated at compile time for storing constants;
  • Code area: The binary code for a function that is the memory mirror of an executable program;

Mach-o is the format for executable files on Mac. A mach-O file has multiple segments, each with a different function. Each Section is then divided into smaller sections

  • TEXT. TEXT: machine code
  • Text. cstring: hardcoded string
  • Text. const: initialized constant
  • Data. DATA: initialized mutable (static/global) DATA
  • Data. const: constant that has not been initialized
  • Data. BSS: uninitialized (static/global) variable DATA.common: uninitialized symbol declaration

You can view the distribution of classes/structures in memory

frame varibale -L xxx
Copy the code

Class and struct selection

If the data structure is simple and the structure can meet the requirements, it is recommended to use the structure. Because the structure of the memory allocation on the stack, the system automatically manage, and for the class system needs to allocate the size of the class memory and destruction operations, compared to the structure performance is worse.