1 Byte Alignment

Associative value byte-alignment rule: The sum of the bytes of the first n-1 argument must be the smallest positive integer multiple of the bytes of the NTH argument or 8 bytes

enum Test{
     case enum1(t1:Int)
     case enum2(t1:Int8,t2:Int16,t3:Int)
     case enum3(t1:Int8,t2:Int,t3:Int16,t4:Int32)
     case enum4(t1:Int8,t2:Int,t3:Int16,t4:Int,t5:Int8,t6:StringEnum1 for)}8Bytes do not need to be aligned to occupy8Exp: enum21.2.8)11Byte, because1Divided by the2If it's not divisible, you have to divide it1into2Occupation becomes (2.2.8), because again2+2In addition to the8If it's not divisible, you have to supplement it4Namely the2into6Take up for (2.6.8) Enum3 occupy (1.8.2.4)15byte because1Divided by the8If it's not divisible, you have to supplement it7A (8.8.2.4At this time),8+8Divided by the2Divisible and unchanged. Let's move on8+8+2Not divisible4Need to fill2A (8.8.4.4Enum4 Special points (1.8.2.8.1.16) because1Not divisible8Therefore, need to fill7
(8.8.2.8.1.16) because8+8aliquot2So the same (8.8.2.8.1.16) because8+8+2Not divisible8So the patch6
(8.8.8.8.1.16) because8+8+8+8aliquot1So the same (8.8.8.8.1.16) because8+8+8+8+1=33When using33Compared to who? We know all the systems are8Byte aligned, expanded16Bytes are bound to waste space, so let's move on8Comparison needs to be made up7
(8.8.8.8.8.16)
Copy the code

2 unify some concepts

Extended bit, real storage bit

case enum1(t1:Int8,t2:Int16) //1 2 ==> 2 2
Copy the code

In this example, the three bytes are expanded to four bytes. The first byte actually stores Int8, the second byte is expanded, and the third and fourth bytes actually store Int16

Invalid bit

If I allocate 8 bytes to store a byte of value, then 2-8 bytes are invalid bits

3 Explore the actual size of enumeration associated values

Normal size of enumeration, maximum value of case bytes aligned +1 byte (storage case type) ———— In special cases, when the maximum item size changes after alignment, Swift will optimize and try to store the case type to the last bit of the extended bit. If this position is also in the extended or invalid bit of another case, the optimization is complete. The occupancy size is the maximum item occupancy size

Let’s look at a couple of examples. Note that x/8g is not the same as memory read. It’s best to use Xcode’s own view memory of “value” to look at the memory distribution

Example 1 enum Test{case Enum1 (T1 :Int) case Enum2 (T1 :Int8, T2 :Int,t3:Int16)} Enum1 8 ==> 8 enum2 1,8,2 ==> 8,8,2 ==> 8 8,8,2 The maximum number of bytes used by Enum2 is 18. Since the first item T1 of Enum2 is expanded to 8 bytes, the system tries to use the eighth byte of enum1 to store the invalid or expanded bits of Int that are not in Enum1. Var b = test. enum2(t1: 1, T2:2, t3: 3) we construct view of memory b b 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 according to 1 July 8 01 t1 = 1 00 00 00 00 00 00 00 00 00 00 02 T2 = 2 00 03 T3 = 3 01 is the case typeCopy the code
Example 2 enum Test{case enum1(t1:Int16) case enum2(t1:Int8,t2:Int,t3:Int16)} align items 2 => 2 1,8,2 => 8,8,2 => 8,8,2 => 8,8,2 As the first item of Enum2 is expanded to 8, the system tries to use the 8th byte to store the type. It judges whether the 8th byte is in the invalid bit or the extended bit of other cases. It finds that the 8th byte is the invalid bit of Enum1 Var b = test. enum2(t1: 1, T2:2, t3: 3) we construct view of memory b b 01 00 00 00 00 00 00 02 80 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 according to 7 1 8 00 00 00 00 00 00 01 is t1 = 1 80 is case type 00 00 00 00 00 00 02 is T2 = 2 00 03 is T3 = 3Copy the code
Example 3 enum Test{case Enum1 (T1 :Int16, T2 :Int) case Enum2 (T1 :Int8, T2 :Int,t3:Int16)} As the first item of Enum2 is expanded, the system tries to determine whether the 8th byte is the invalid bit or the extended bit of other cases. It finds that the 3rd byte to the 8th byte of Enum1 is the extended bit and the type can be stored here to occupy the 18th byte storage type  var b = Test.enum2(t1: 1, t2: 2, t3: 3) we construct view of memory b b 01 00 00 00 00 00 00 02 80 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 according to 7 1 8 00 00 00 00 00 00 01 is t1 = 1 80 is case type 00 00 00 00 00 00 02 is T2 = 2 00 03 is T3 = 3Copy the code

All of the above proves this conclusion

Normally, enumerations with associated values take up the maximum value of each case byte aligned +1 byte (store case type) ———— In particular, when the largest item changes due to alignment, Swift will optimize, trying to store the case type to the last bit of the extended bit. If this position is also in the extended or invalid bit of another case, the optimization is complete. The occupancy size is the maximum item occupancy size

Let’s do another example

Example 4 enum Test {case enum1 (t1: Int, t2: Int) case enum2 (t1: Int8, t2: Int, t3: Int16, t4: Int)} to alignment algorithm based on the first 8, 8 = = > 8, 8 1,8,2,8 = = > 8,8,2,8 = = > 8,8,8,8 concluded that maximum enum2 32 because of the expansion of the system the first t1 enum2 try to 8 bytes storage type Whether 8 bytes in the other case is invalid or expanded a find enum1 8 bytes used to store the t1 is not appropriate Var b = test.enum2 (t1: t1) var b = test.enum2 (t1: t1) var b = test.enum2 (t1: t1) 1, t2: 2, t3: 3, t4: 4) we construct view of memory b b 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 03 00 00 00 00 00 00 80 04 00 00 00 00 00 00 00 we according to the August 8 7 1 8 reads 00 00 00 00 00 00 00 00 01 is t1 = 1 00 00 00 00 00 00 00 00 00 02 is T2 = 2 00 00 00 00 00 00 00 00 00 00 00 03 is T3 = 3 80 is case type 00 00 00 00 00 00 00 04 t4 = 4Copy the code

Following our reasoning, we see that if the maximum item byte alignment is extended, the system will try to populate the 1-byte case type at the end of the extension. To save resources

What if associative enumerations were more complicated?

Case 5 enum Test {case enum1 (t1: Int, t2: Int8, t3: Int, t4: String) case enum2 (t1: Int8, t2: Int, t3: Int16, t4: Int, t5, Int8, t6: String)} Aligned on the first 8 8,8,8,16,1,8,16 = = > 1,8,2,8,1,16 = = > 8,8,2,8,1,16 = = > 8,8,8,8,1,16 = = > 8,8,8,8,8,16 maximum enum2 to 56 Since the first entry t1 of Enum2 is expanded, the system will try to store the type of the 8th byte to determine whether the 8th byte is invalid in other cases or if the 8th byte of Enum1 is found to be inappropriate to store T1. Then the system will try to store the type of the 24th byte after getting the second entry T3 of Enum2 If byte 17 to 24 of Enum1 is not suitable to store T3, the system will try to determine whether byte 40 is invalid or extended in other cases by storage type of byte 40 Var b = test. enum2(T1:1, T2:2, T3:3, T4:4, T5:5,t6: "1"), we construct view of memory b b 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 05 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 01 00 00 00 00 00 00 00 we according to 8 8 8 8 8 16 1 00 00 00 00 00 00 00 00 00 00 00 00 01 t1 = 1 00 00 00 00 00 00 00 00 02 T2 = 2 00 00 00 00 00 00 00 00 00 00 00 00 03 T3 = 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 T4 = 4 00 00 00 00 00 05 t5 = 5 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 T6 = 1 01 is a case typeCopy the code

4 summarizes

Byte alignment:

The total number of bytes used by the first n−1 parameter must be the smallest positive multiple of the number of bytes used by the NTH parameter (if the number of bytes used is greater than 8, take 8 as the dividend)

Enumeration size of associated values:

After byte alignment, the largest byte Max is taken. If it is extended, try to determine whether the last bit of all extended parameters is invalid bit or extended bit of other case items. If such a position exists, the total occupation of 1 byte can be optimized to Max, and the case type is stored in the last byte of the extension. The case type is stored in the Max +1 byte if the maximum item is not found or not expanded.