Swift. Types, function calls

Swift. Types, function calls

Delayed storage properties

  • uselazy decorated storage attributes
  • Delayed storage attributes must have a default initial value
  • Will be assigned at the first visit
  • Does not guarantee thread safety
  • Impact on the size of instance objects

Must have an initial value and cannot be marked as an optional value, otherwise an error will be reported

It can be seen from the figure above that there is no value in the memory when the first breakpoint is reached. The first two are metadatasumsrefCounts when the next breakpoint is reached, the memory information is printed again, and the value is only available when you view it. Assignment will only be performed when the delayed storage attribute of age is accessed for the first time

From the above two pictures, you can see that the memory size after lazysum lazyhas changed. Look at the sil file specifically.lazy var age: Int = 18 is an optional type at the bottom (the default is nil, memory 0x0), and it is accessed when it is accessed for the first time. The getter method, according to the branch of the enumeration value, judges that there is no value, enters the corresponding branch to perform the assignment operation

ViewOptional memory

According to the above can be learned through in the bottom layer lazyafter modification inttypes are Optionaloptional type, see Optionalhis essence is enuman enumeration, there are none sometwo enumeration values, where nonethere is no value, accounting 1 , somethere is value accounting 8 so Optionalon the possession 9 , but according to the word The principle of section alignment must 8 be carried out if it is to be carried out , so it will be filled in 16 ; so we can learn from the previous

metadata(8) +refCounts(8)+Optional(16) = 32

So the size of the storage attribute after lazy modification is influential

Then go back to the getter method of the sil file above to view the two threads accessing the getter method, 1check that there is no value, jump bb2, at this moment cpu 2, 1stop there and have not finished execution, the current is Optionalstill nil, it 2will still jump to bb2For this branch, at this time, the time slices are allocated 1for execution. After execution bb2, the time slices are allocated 2again and executed again bb2. lazy

Type attribute

  • Use static keyword modification
  • The type attribute must have a default initial value
  • The type attribute will only be initialized once

Check the sil file, because the age gettermethod is called, so look at the getter method directly. swift_once GCD is called dispatch_once_fto ensure thread safety

The method can be rewritten as swift sharedInstancea global constant, and it will only be initialized once, and then initset the method privateto be directly called externallyshareInstance


The difference between Class and Struct in initialization

From the figure can be seen in the creation of the body structure instance is the default prompt to help us out parameter assignment to view the file sil structdefault is to help us generate initfunctions, whileclass that we need to manually create

Struct type

Value type

Struct is a value type

The value is stored directly, and the value is copied.

Class is a reference type

For the address, the address is stored in the address, not the value. If the address on the heap space is copied out, other variables will also access the corresponding value in the heap address. .

mutating and inout

Write a method similar to the stack structure in the structure, prompting an error, temporarily comment out append and replace it with print

Look at the sil file again to see itmethat there is a parameter in addition to push self. This selfis Stackand is letof the type let , so when we itmes stack , itmes is actually a shorthand for self.itmes.

Add mutating keyword

Look again at the sil file. The original file has letbecome var, varvariable, and what you get now is Stack that it was not obtained directly before , so mutatingthis keyword is a @inoutkeyword added to him by default , which is mutatingonly useful in it , because there The modified one is his

Seen from the example of the official , but added inoutafter a successful key exchange, and then view from above, like adding a sil file inoutafter the keyword is taken , and also the

Static call of function

struct Stack {
     func teach() {
var t = Stack()

How does the above code call the teach function? Assembly can be seen from FIG pattern look directly address and sign function, the executable file into MachOView view _TEXT,_textis the code segment, all code segments contains assembler instructions executable, teach a search appears in the top 0x100002b70The address of this function is the same as that seen in assembly mode. You can see the address of the function directly in MachOView, because this address has been determined after the compilation and linking is completed. All struct function calls are static calls


In the above there is a compilation of figures SwiftTest.Stack.teach()symbol from a symbol table as he is the symbol table, but he does not directly stored symbols,

String table

The string table stores everything in the form of strings

View all symbols through the terminal

Enter nmthen the executable file into the terminal can also xcrun swift-demanglebe also by find

releaseCompile in the environment, you will find an extra DSYMfile (this file is used to locate the crash in the online project). At this time, drag the executable file into MachOView to view it. Search for teach in the symbol table and find that there is nothing. Because in the release environmentstrip these symbols dropped , statically linked functions do not need symbols. Once the compilation is completed, the symbol table will strip these symbols, and the rest are some uncertain addresses like the first time Lazy Symbol Pointers The address is generated only when it is called, and cannot be stripped off

Function overloading

Create a new c project and drag the executable file to machoview to view the symbol table after renamed

The oc project is selectorsearched imp, but the two function names are the same imp of the

swift engineering


Create a new project and check the assembly with a break point. Each time the APP is started, one will be generated ASLR . The symbol address determined during compilation and linking, plus the randomly generated ASLR offset value, will be the correct symbol address at runtime. Enter image listit in the console . When it appears, drag the executable file into MachOView to view load Commandsit, LC_SEGMENT_64(_TEST)and find VM Address, this is ,

 - = (ASLR)

Under verified 0x0000000006cbd000as ASLR 0x0000000100003ad0to compile link address

Use the nmcommand to list the symbol table in the terminal to search and then use the xcruncommand to restore the symbol perfect restoration