Delayed storage properties
- use
lazy
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 metadata
sumsrefCounts
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 lazy
sum lazy
has 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 lazy
after modification int
types are Optional
optional type, see Optional
his essence is enum
an enumeration, there are none
some
two enumeration values, where none
there is no value, accounting 1
, some
there is value accounting 8
so Optional
on 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, 1
check that there is no value, jump bb2
, at this moment cpu 2
, 1
stop there and have not finished execution, the current is Optional
still nil
, it 2
will still jump to bb2
For this branch, at this time, the time slices are allocated 1
for execution. After execution bb2
, the time slices are allocated 2
again 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 getter
method is called, so look at the getter method directly. swift_once
GCD is called dispatch_once_f
to ensure thread safety
The method can be rewritten as swift
sharedInstance
a global constant, and it will only be initialized once, and then init
set the method private
to be directly called externallyshareInstance
Structure
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
struct
default is to help us generate init
functions, 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 itme
that there is a parameter in addition to push self
. This self
is Stack
and is let
of 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 let
become var
, var
variable, and what you get now is Stack
that it was not obtained directly before
, so mutating
this keyword is a @inout
keyword added to him by default , which is mutating
only
useful in
it
, because
there The modified one is his
Seen from the example of the official
, but added inout
after a successful key exchange, and then view from above, like adding a sil file inout
after the keyword is taken
, and also
the
Static call of function
struct Stack {
func teach() {
print("teach")
}
}
var t = Stack()
t.teach()
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,_text
is the code segment, all code segments contains assembler instructions executable, teach a search appears in the top 0x100002b70
The 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
symbol
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 nm
then the executable file into the terminal can also xcrun swift-demangle
be
also by
find
release
Compile in the environment, you will find an extra DSYM
file (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 selector
searched imp
, but the two function names are the same imp
of the
swift engineering
ASLR
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 list
it in the console . When it appears,
drag the executable file into MachOView to view load Commands
it, LC_SEGMENT_64(_TEST)
and find VM Address
, this is
,
- = (ASLR)
Under verified
0x0000000006cbd000
as ASLR
0x0000000100003ad0
to compile link address
Use the nm
command to list the symbol table in the terminal to search and then use the xcrun
command to restore the symbol perfect restoration