├── SwiftDemo
├── SwiftDemo
│ └── main.swift
└── SwiftDemo.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── jintao.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ └── jintao.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ ├── xcshareddata
│ └── xcschemes
│ │ └── SwiftDemo.xcscheme
│ └── project.pbxproj
├── Swift
├── Struct.swift
├── Tuple.swift
├── Enum.swift
├── Protocol.swift
└── Class.swift
├── SwiftCore
├── Bool.swift
├── Character.swift
├── Optional.swift
├── Array.swift
├── Set.swift
├── Dictionary.swift
└── String.swift
└── README.md
/SwiftDemo/SwiftDemo/main.swift:
--------------------------------------------------------------------------------
1 | //
2 | // main.swift
3 | // SwiftDemo
4 | //
5 | // Created by jintao on 2019/8/7.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/xcuserdata/jintao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.xcworkspace/xcuserdata/jintao.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TannerJin/Swift-MemoryLayout/HEAD/SwiftDemo/SwiftDemo.xcodeproj/project.xcworkspace/xcuserdata/jintao.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Swift/Struct.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Struct.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/7.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // struct StructValue { (for memory alignment)
12 | // let a: Int8 = 4 |
13 | // let b: Int16 = 6 ==> 04 00 06 00 08 00 00 00
14 | // let c: Int32 = 8 | \ / \ /
15 | // } a b c
16 |
17 |
18 | // FYI: if you want to get the offset of each property at runtime, you can see https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst
19 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/xcuserdata/jintao.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A947488F22FACE8F00212E57
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftCore/Bool.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Bool.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/1.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Bool {
12 | // struct Bool
13 | // +-----------------------------------------------------------------------+
14 | // | var _value: Int8 1: true ; others: false |
15 | // +-----------------------------------------------------------------------+
16 |
17 | var valuePointer: UnsafeMutablePointer {
18 | mutating get {
19 | return withUnsafePointer(to: &self) { (pointer) -> UnsafeMutablePointer in
20 | UnsafeMutablePointer(OpaquePointer(pointer))
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Swift/Tuple.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tuple.swift
3 | // SwiftDemo
4 | //
5 | // Created by jintao on 2019/8/13.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // typealias TupleValue = (Int8, Int16, Int32)
12 | // ∧ \
13 | // | \
14 | // | same layout |
15 | // | |
16 | // V V
17 | //
18 | // struct StructValue { 04 00 06 00 08 00 00 00
19 | // let a: Int8 = 4 | | \ / \ /
20 | // let b: Int16 = 6 -----> a | b c
21 | // let c: Int32 = 8 V
22 | // } (for memory alignment)
23 |
--------------------------------------------------------------------------------
/SwiftCore/Character.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Character.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/1.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Character {
12 | // struct Character
13 | // +-----------------------------------------------------------------------+
14 | // | var _str: String unicode |
15 | // +-----------------------------------------------------------------------+
16 |
17 | // UTF-8 => use 1 ~ 4 bytes (one can byte compatible ASCII, 0x00...0x7F)
18 | // /
19 | // unicode - UTF-16 => use 2/4 bytes
20 | // \
21 | // UTF-32 => use 4 bytes
22 |
23 | var valuePointer: UnsafeMutableRawPointer {
24 | mutating get {
25 | // unicode.bytes.count <= 15
26 | return withUnsafePointer(to: &self) { UnsafeMutableRawPointer(mutating: $0) }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SwiftCore/Optional.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Optional.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/1.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Optional {
12 | // enum Optional
13 | // +-----------------------------------------------------------------------+
14 | // | case none |
15 | // | case some(Wrapped) |
16 | // +-----------------------------------------------------------------------+
17 |
18 | // Optional.bytes count => 1 + Wrapped.bytes count
19 |
20 | // longjmp to Enum.Swift
21 | // Int8? = nil : Optional.none => 00 01 00 => self at all not associated enum's value ; 01 => all associated enum count
22 | // Int8? = 4 : Optional.some => 04 00 04 => associated value ; 00 => self at all associated enum's value
23 |
24 | var valuePointer: UnsafeMutableRawPointer {
25 | mutating get {
26 | return withUnsafePointer(to: &self) { UnsafeMutableRawPointer(mutating: $0) }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Swift/Enum.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Enum.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/6.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // enum EnumValue { => 1 byte
12 | // case a 0x00
13 | // case b 0x01
14 | // case c 0x02
15 | // case d 0x03
16 | // }
17 |
18 |
19 | // enum EnumValue: String { => 1 byte
20 | // case a = "a" 0x00
21 | // case b 0x01
22 | // case c 0x02
23 | // case d = "d" 0x03
24 | // }
25 |
26 |
27 | // enum EnumValue { => 17 bytes(ingore memory align)
28 | // case a enum's size + max association's type of enum = 1 + 16(String)
29 | // case b(String)
30 | // case c(Int32)
31 | // case d
32 | // case f(Int64)
33 | // case e
34 | // }
35 | // |
36 | // |
37 | // V
38 | // +----------------------------------------+ --
39 | // | case a 00 count | \
40 | // | case d 01 count | offset(1 byte) + all count of enums with association(b, c, f; count = 3)
41 | // | case e 02 count | /
42 | // | |
43 | // | case b(String) string 00 | \
44 | // | case c(Int32) Int32 01 | association's value(16 bytes) + offset(1 byte)
45 | // | case f(Int64) Int64 02 | /
46 | // +----------------------------------------+ --
47 |
--------------------------------------------------------------------------------
/SwiftCore/Array.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/7/31.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Array {
12 | // struct Array
13 | // +--------------------------------------------------------------------+
14 | // | struct _ArrayBuffer (_ContiguousArrayBuffer) |
15 | // +----/----------------------------------------|----------------------+
16 | // / /
17 | // |(objc) |(nonobjc)
18 | // V V
19 | // class __ContiguousArrayStorageBase (_ContiguousArrayStorage)
20 | // +-----------------------------------------------------------------------+
21 | // | var isa: UnsafeMutableRawPointer |
22 | // | var refcount: Int |
23 | // | var countAndCapacity: _ArrayBody |
24 | // +------------------------------|----------------------------------------+
25 | // /
26 | // |
27 | // V
28 | // struct _ArrayBody
29 | // +-----------------------------------------------------------------------+
30 | // | struct _SwiftArrayBodyStorage |
31 | // | +--------------------------------------------------------------+ |
32 | // | | var count: Int // 16 bytes offset | |
33 | // | | var _capacityAndFlags: Int | |
34 | // | | var sequence: [Element] // 32 bytes offset | |
35 | // | +--------------------------------------------------------------+ |
36 | // +-----------------------------------------------------------------------+
37 |
38 | // count address
39 | var countPointer: UnsafeMutablePointer {
40 | get {
41 | let pointer = unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 16)
42 | return pointer.assumingMemoryBound(to: Int.self)
43 | }
44 | }
45 |
46 | // sequence address
47 | var valuePointer: UnsafeMutablePointer {
48 | get {
49 | let pointer = unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 32)
50 | return pointer.assumingMemoryBound(to: Element.self)
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/SwiftCore/Set.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Set.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/1.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Set {
12 | // struct Set Element: Hashable
13 | // +------------------------------------------------+
14 | // | struct Set._Variant |
15 | // | +------------------------------------------+ |
16 | // | | var objc: __RawSetStorage | |
17 | // | +--------------|---------------------------+ |
18 | // +-----------------/------------------------------+
19 | // |
20 | // |
21 | // V
22 | // class __RawSetStorage
23 | // +-----------------------------------------------------------------------+
24 | // | var isa: UnsafeMutableRawPointer |
25 | // | var refcount: Int |
26 | // | var _count: Int // 16 byte offset |
27 | // | var _capacity: Int |
28 | // | var _scale: Int8 |
29 | // | var _reservedScale: Int8 |
30 | // | var _extra: Int16 |
31 | // | var _age: Int32 |
32 | // | var _seed: Int |
33 | // | var _rawElements: UnsafeMutableRawPointer // 48 byte offset |
34 | // | var _bucketCount: Int |
35 | // | var _metadata: UnsafeMutablePointer<_HashTable.Word> |
36 | // | var _hashTable: _HashTable |
37 | // +-----------------------------------------------------------------------+
38 |
39 | // count value of address
40 | var countPointer: UnsafeMutablePointer {
41 | get {
42 | return unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 16).assumingMemoryBound(to: Int.self)
43 | }
44 | }
45 |
46 | // array of values address
47 | var valuesPointer: UnsafeMutablePointer {
48 | get {
49 | let valuesAddrValue = unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 48).assumingMemoryBound(to: Int.self).pointee
50 | return UnsafeMutableRawPointer(bitPattern: valuesAddrValue)!.assumingMemoryBound(to: Element.self)
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Swift/Protocol.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Protocol.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/6.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // protocol
12 | // +-----------------------------------------------------------------------+
13 | // | var payload_data_0 8 bytes | --
14 | // | var payload_data_1 8 bytes | payload_data => 24 bytes store instance_type's data
15 | // | var payload_data_2 8 bytes | -- |
16 | // | --------------------------------------------------- | |
17 | // | var instance_type: Any.Type 8 bytes | |
18 | // | var witness_table_protocol: UnsafeMutableRawPointer 8 bytes | |
19 | // +--------------|--------------------------------------------------------+ |
20 | // | |
21 | // V V
22 | // witness_table
23 | // +----------------------------------------+ if instance_type.size <= 24 {
24 | // | data: pointer | payload_data = instance
25 | // | protocol_method_0: void* | } else {
26 | // | protocol_method_1: void* | payload_data = instance*
27 | // | protocol_method_2: void* | }
28 | // | . |
29 | // | . |
30 | // +----------------------------------------+
31 | // ∧
32 | // |
33 | // +-------------------------------------------------------------+
34 | // |
35 | // |
36 | // protocol: class |
37 | // +-----------------------------------------------------------------------+ |
38 | // | var instance: UnsafeMutableRawPointer | |
39 | // | var witness_table_protocol: UnsafeMutableRawPointer | |
40 | // +-------------|---------------------------------------------------------+ |
41 | // | |
42 | // +--------------------------------------------------------------+
43 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/xcshareddata/xcschemes/SwiftDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/SwiftCore/Dictionary.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/7/31.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Dictionary {
12 | // struct Dictionary
13 | // +------------------------------------------------+
14 | // | enum Dictionary._Variant |
15 | // | +--------------------------------------------+ |
16 | // | | [struct _NativeDictionary | |
17 | // | +---|----------------------------------------+ |
18 | // +----/-------------------------------------------+
19 | // /
20 | // |
21 | // V
22 | // class __RawDictionaryStorage
23 | // +-----------------------------------------------------------------------+
24 | // | var isa: UnsafeMutableRawPointer |
25 | // | var refcount: Int |
26 | // | var _count: Int // 16 byte offset |
27 | // | var _capacity: Int |
28 | // | var _scale: Int8 |
29 | // | var _reservedScale: Int8 |
30 | // | var _extra: Int16 |
31 | // | var _age: Int32 |
32 | // | var _seed: Int |
33 | // | var _rawKeys: UnsafeMutableRawPointer // 48 byte offset -----------------------+
34 | // | var _rawValues: UnsafeMutableRawPointer // 56 byte offset -----------------------+---------------+
35 | // | var _bucketCount: Int | | |
36 | // | var _metadata(get): UnsafeMutablePointer<_HashTable.Word> -----------------+ | |
37 | // | var _hashTable(get): _HashTable | | | |
38 | // +-----------------------------------------------------------------------+ | | |
39 | // | | |
40 | // | | |
41 | // | | |
42 | /* Dictionary | | |
43 | | | | |
44 | V | | |
45 | +-------------------------------------+ | | |
46 | | RawDictionaryStorage (MetaData) | | | |
47 | | | | | |
48 | +-------------------------------------+ <----------------------------------------------+ | |
49 | | Word (Hash Offset) | | |
50 | | | | |
51 | +-------------------------------------+ <----------------------------------------------------+ |
52 | | Keys | |
53 | | | |
54 | +-------------------------------------+ <--------------------------------------------------------------------+
55 | | Values |
56 | | |
57 | +-------------------------------------+
58 |
59 | Word (Hash Offset)
60 | |
61 | V 64(32) bits
62 | / \
63 | if Word[0] = 0b1000000...0000000000100 => Keys[2] != nil and Keys[63] != nil
64 | if Word[1] = 0b1000000...0000000000101 => Keys[64] != nil and Keys[66] != nil and ...
65 |
66 | set: var bitOffset = hash(NewKey) & bucketCount
67 | when bitOffset of Word is occupied(bit is 1) {
68 | bitOffset += 1
69 | }
70 |
71 | set the bit of Word with bitOffset to 1
72 | Keys[bitOffset] = NewKey
73 | Values[bitOffset] = NewValue
74 |
75 |
76 | get: var bitOffset = hash(Key) & bucketCount
77 | when Keys[bitOffset] != Key {
78 | bitOffset += 1
79 | }
80 | return Values[bitOffset]
81 | */
82 |
83 |
84 |
85 | // count value of address
86 | var countPointer: UnsafeMutablePointer {
87 | get {
88 | return unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 16).assumingMemoryBound(to: Int.self)
89 | }
90 | }
91 |
92 | // array of keys address
93 | var keysPointer: UnsafeMutablePointer {
94 | get {
95 | let keysAddrValue = unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 48).assumingMemoryBound(to: Int.self).pointee
96 | return UnsafeMutableRawPointer(bitPattern: keysAddrValue)!.assumingMemoryBound(to: Key.self)
97 | }
98 | }
99 |
100 | // array of values address
101 | var valuesPointer: UnsafeMutablePointer {
102 | get {
103 | let valuesAddrValue = unsafeBitCast(self, to: UnsafeMutableRawPointer.self).advanced(by: 56).assumingMemoryBound(to: Int.self).pointee
104 | return UnsafeMutableRawPointer(bitPattern: valuesAddrValue)!.assumingMemoryBound(to: Value.self)
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swift MemoryLayout
2 |
3 | **swift version =>: swift 5.0**
4 |
5 | - [Swift](#Swift)
6 | - [Struct](#Struct)
7 | - [Tuple](#Tuple)
8 | - [Class](#Class)
9 | - [Protocol](#Protocol)
10 | - [Enum](#Enum)
11 | - [SwiftCore](#SwiftCore)
12 | - [Bool](#Bool)
13 | - [Optional](#Optional)
14 | - [String](#String)
15 | - [Character](#Character)
16 | - [Array](#Array)
17 | - [Set](#Set)
18 | - [Dictionary](#Dictionary)
19 |
20 |
21 | ## Swift
22 |
23 | ### [Struct](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/Swift/Struct.swift)
24 |
25 | ```swift
26 | struct StructValue {
27 | let a: Int8 = 4
28 | let b: Int16 = 6
29 | let c: Int32 = 8
30 | }
31 |
32 | var structValue = StructValue()
33 | let structValuePointer = withUnsafePointer(to: &structValue) { UnsafeMutableRawPointer(mutating: $0) }
34 | structValuePointer.advanced(by: 2).assumingMemoryBound(to: Int16.self).initialize(to: 99)
35 |
36 | // structValue.b = 99
37 | ```
38 |
39 | ### [Tuple](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/Swift/Tuple.swift)
40 |
41 | ```swift
42 | typealias TupleValue = (Int8, Int32, String)
43 |
44 | struct StructValue {
45 | var a: Int8 = 4
46 | var b: Int32 = 5
47 | var c: String = "SwiftTuple"
48 | }
49 |
50 | let structValue = StructValue()
51 | let tupleValue = unsafeBitCast(structValue, to: TupleValue.self)
52 | print(tupleValue.1)
53 |
54 | // print 5 (structValue.b)
55 |
56 | // if TupleValue = (Int8, Int8, String) => MemoryLayout of TupleValue != MemoryLayout of StructValue
57 | ```
58 |
59 | ### [Class](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/Swift/Class.swift)
60 |
61 | ```swift
62 | class A {
63 | var a = 666
64 | }
65 |
66 | let a1 = A()
67 | unowned let unowned_a = a1
68 | let a2 = a1
69 |
70 | weak var weak_a = a1
71 | weak var weak_a2 = a1
72 |
73 | unowned let unowned_a2 = a1
74 |
75 | let a3 = a2
76 | let a4 = a2
77 | weak var weak_a3 = a1
78 | unowned let unowned_a3 = a1
79 |
80 | print(UnownedRefCount(a1))
81 | print(WeakRefCount(a1)!)
82 | print(StrongRefCount(a2))
83 | ```
84 |
85 | ### [Protocol](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/Swift/Protocol.swift)
86 |
87 | ```swift
88 | // test with debug
89 | protocol SwiftProtocol {
90 | func foo()
91 | func foo2()
92 | }
93 |
94 | struct StructValue: SwiftProtocol {
95 | func foo() {
96 | print("foo")
97 | }
98 |
99 | func foo2() {
100 | print("foo2")
101 | }
102 | }
103 |
104 | var Protocol: SwiftProtocol = StructValue()
105 | let protocol_pointer = withUnsafePointer(to: &Protocol) { UnsafeMutableRawPointer(mutating: $0) }
106 |
107 | let witness_table_pointer_value = protocol_pointer.advanced(by: 32).assumingMemoryBound(to: UInt.self).pointee
108 | let witness_table_pointer = UnsafeMutablePointer.init(bitPattern: witness_table_pointer_value)
109 |
110 | typealias Foo2Method = @convention(thin) ()->Void
111 |
112 | let witness_foo2_pointer = unsafeBitCast(witness_table_pointer!.advanced(by: 2).pointee, to: Foo2Method.self)
113 | witness_foo2_pointer()
114 |
115 | // print foo2
116 | ```
117 |
118 | ### [Enum](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/Swift/Enum.swift)
119 |
120 | ```swift
121 | enum EnumValue {
122 | case a
123 | case b(String)
124 | case c(Int32)
125 | case d
126 | case f(Int64)
127 | case e
128 | }
129 |
130 | var enumC = EnumValue.c(8)
131 | let enumCPointer = withUnsafePointer(to: &enumC) { UnsafeMutableRawPointer(mutating: $0) }
132 | enumCPointer.advanced(by: 16).assumingMemoryBound(to: Int8.self).initialize(to: 0x02)
133 |
134 | // enumC = EnumValue.f(8)
135 | ```
136 |
137 |
138 | ## SwiftCore
139 |
140 | ### [Bool](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Bool.swift)
141 |
142 | ```swift
143 | var bool = true
144 | let boolPointer = bool.valuePointer
145 | boolPointer.initialize(to: -10)
146 |
147 | // bool = false
148 | ```
149 |
150 | ### [Optional](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Optional.swift)
151 |
152 | ```swift
153 | var optional: Int16? // 0x00 0x00 0x01
154 | var optionalPointer = optional.valuePointer
155 | optionalPointer.assumingMemoryBound(to: Int16.self).initialize(to: 99) // 0x63 0x00 0x01
156 | optionalPointer.advanced(by: MemoryLayout.size).assumingMemoryBound(to: UInt8.self).initialize(to: 0x00) // 0x63 0x00 0x00
157 |
158 | // optional = 99
159 | ```
160 |
161 | ### [String](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/String.swift)
162 |
163 | ```swift
164 | var string = "TannerJin"
165 | let stringPointer = string.valuePointer
166 | stringPointer.assumingMemoryBound(to: Int8.self).initialize(to: 0x40) // 0x40 => "@"
167 |
168 | // string = "@anner Jin"
169 | ```
170 |
171 | ### [Character](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Character.swift)
172 |
173 | ```swift
174 | var character = Character("😂")
175 | let characterPointer = character.valuePointer.assumingMemoryBound(to: UInt8.self)
176 | characterPointer.initialize(to: 0xf0) // f0 9f 9a 80 => "🚀" unicode(utf-8)
177 | characterPointer.advanced(by: 1).initialize(to: 0x9f)
178 | characterPointer.advanced(by: 2).initialize(to: 0x9a)
179 | characterPointer.advanced(by: 3).initialize(to: 0x80)
180 |
181 | // character = "🚀"
182 | ```
183 |
184 | ### [Array](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Array.swift)
185 |
186 | ```swift
187 | let array = ["Apple", "Swift"]
188 | let arrayPointer = array.valuePointer
189 | arrayPointer.initialize(to: "Tanner")
190 |
191 | // array = ["Tanner", "Swift"]
192 |
193 | array.countPointer.initialize(to: 3)
194 |
195 | // array.count = 3
196 | ```
197 |
198 | ### [Set](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Set.swift)
199 |
200 | ```swift
201 | let set: Set = ["Apple", "iOS", "Swift"]
202 | set.valuesPointer.initialize(to: "Tanner")
203 |
204 | // set = ["Tanner", "Swift", "iOS"] || ["Tanner", "Swift", "Apple"] || ...
205 |
206 | set.countPointer.initialize(to: 2)
207 |
208 | // set.count = 2
209 | ```
210 |
211 | ### [Dictionary](https://github.com/TannerJin/Swift-MemoryLayout/blob/master/SwiftCore/Dictionary.swift)
212 |
213 | ```swift
214 | let dictionary = ["Swift": 5.0, "iOS": 2019]
215 |
216 | let dicCountPointer = dictionary.countPointer
217 | let dicKeysPointer = dictionary.keysPointer
218 | let dicValuesPointer = dictionary.valuesPointer
219 | ```
220 |
--------------------------------------------------------------------------------
/SwiftCore/String.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/7/31.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // struct String
12 | // +------------------------------------------------+
13 | // | struct _StringGuts |
14 | // | +--------------------------------------------+ |
15 | // | | struct _StringObject | |
16 | // | | +----------------------------------------+ | |
17 | // | | | #if arch(i386) || arch(arm) | | |
18 | // | | | | | |
19 | // | | | --- 32-bit platforms --- | | |
20 | // | | | | | |
21 | // | | | enum Variant { | | |
22 | // | | | case immortal(UInt) | | |
23 | // | | | case native(AnyObject) | | |
24 | // | | | case bridged(_CocoaString) | | |
25 | // | | | } | | |
26 | // | | | var count: UInt | | |
27 | // | | | var _variant: Variant | | |
28 | // | | | var _discriminator: UInt8 | | |
29 | // | | | var _flags: UInt16 | | |
30 | // | | | var _countAndFlagsBits: UInt64 | | |
31 | // | | | | | |
32 | // | | | #else | | |
33 | // | | | | | |
34 | // | | | --- 64-bit platforms --- | | |
35 | // | | | | | |
36 | // | | | var _countAndFlagsBits: UInt64 | | |
37 | // | | | var _object: Builtin.BridgeObject | | |
38 | // | | | | | |
39 | // | | | #endif | | |
40 | // | | +----------------------------------------+ | |
41 | // | +--------------------------------------------+ |
42 | // +------------------------------------------------+
43 | // +--------------------------------------+
44 | // | |
45 | // | |
46 | // / count <= 15, Small => 15 bytes(string) + 1 byte(_object.abcdeeee) \ |
47 | // String 16 bytes |
48 | // \ count > 15, Large => 8 bytes(_countAndFlagsBits) + 8 bytes(_object) / |
49 | // | | |
50 | // | | |
51 | // +---------------------------------------------+ +------------------------------+
52 | // | |
53 | // | |
54 | // | |
55 | // V |
56 | // _countAndFlagsBits (64 bits) |
57 | // |
58 | // abcd a => isASCII b => isNFC |
59 | // ∧∧∧∧ c => isNativelyStored d => isTailAllocated |
60 | // |||| |
61 | // 0000000000000000000000000000000000000000000000000000000000000000 |
62 | // | || | |
63 | // \ 16 bits / \ 48 bits / |
64 | // \ flags / \ count for Large String / |
65 | // \________/ \________________________________________/ |
66 | // |
67 | // |
68 | // |
69 | // |
70 | // +----------------------------------------------------------------------------------------------------+
71 | // |
72 | // |
73 | // V
74 | // _object (64 bits)
75 | //
76 | // abcdeeee a => isImmortal b => largeIsCocoa e(4 bits) => count of Small String
77 | // ∧∧∧∧∧∧∧∧ c => isSmall d => providesFastUTF8
78 | // ||||||||
79 | // 0000000000000000000000000000000000000000000000000000000000000000
80 | // | || |
81 | // \ / \ 56 bits /
82 | // \ / \ pointer for Large String /
83 | // + \________________________________________________/
84 | // |
85 | // V
86 | // 8 bits, 1 byte
87 |
88 |
89 | public extension String {
90 | var valuePointer: UnsafeMutableRawPointer? {
91 | mutating get {
92 | #if arch(i386) || arch(arm)
93 | // 32-bit platforms wati to do
94 | return nil
95 | #else
96 | if self.count <= 15 {
97 | // - Small strings
98 | return withUnsafePointer(to: &self) { UnsafeMutableRawPointer(mutating: $0) }
99 | } else {
100 | // - Large strings
101 | let _object = unsafeBitCast(self, to: (UInt64, UInt64).self).1
102 | let pointerMask = 1 << 56 - 1 // 56 bits => 111...111
103 | let pointerValue = _object & UInt64(pointerMask)
104 | return UnsafeMutableRawPointer(bitPattern: UInt(pointerValue))?.advanced(by: 32)
105 | }
106 | #endif
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Swift/Class.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Class.swift
3 | // SwiftPointerDemo
4 | //
5 | // Created by jintao on 2019/8/2.
6 | // Copyright © 2019 jintao. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // class
12 | // +-----------------------------------------------------------------------+
13 | // | var isa: objc_class* |
14 | // | var refCount: UInt64 >>>>>>>>---------------------------------------------------------+
15 | // |- - - - - - - - - - - - - - - - - | |
16 | // | var property0: String | |
17 | // | var property1: [Int] | |
18 | // | . | |
19 | // | . | |
20 | // | . | |
21 | // +-----------------------------------------------------------------------+ |
22 | // |
23 | // |
24 | // +------------------------------------------------------------------------+
25 | // |
26 | // V
27 | // InlineRefCountBits (64 bits)
28 | // 0000000000000000000000000000000000000000000000000000000000000000
29 | // || ||| ||
30 | // | \ 30 bits / | \ 31 bits / |
31 | // | \ StrongExtraRefCount / | \ UnownedRefCount / |
32 | // | \______________________/ | \_______________________/ |
33 | // | | |
34 | // V V V
35 | // UseSlow(1 bit) IsDeiniting(1 bit) IsImmortal(1 bit)
36 |
37 | // or
38 | // (is Static Object 单例)
39 | // ∧ ∧
40 | // | |
41 | // | HeapObjectSideTableEntry* (64 bits) |
42 | // 0000000000000000000000000000000000000000000000000000000000000000
43 | // || |
44 | // | \ 62 bits /
45 | // | \ HeapObjectSideTableEntry* /
46 | // | \______________________________________________________/
47 | // |
48 | // V
49 | // SideTableMark(1 bit)
50 |
51 | /* HeapObject:
52 |
53 | if (StrongExtraRefCount or UnownedRefCount is overFlow) or hasWeakRef {
54 | Use HeapObjectSideTable
55 | }
56 |
57 | struct HeapObjectSideTable {
58 | let object: UnsafeMutableRawPointer
59 | let bits: (UInt64, Int64) // include StrongExtraRefCount and UnownedRefCount
60 | let weakBits: UInt32
61 | }
62 |
63 | each weak variable(WeakReference) will pointe to the same HeapObjectSideTable of the headObject, so *weak_variable = (heapObject*)objc
64 |
65 | for example:
66 | class A {
67 | }
68 | let a = A()
69 | weak var a2 = a // a2 is pointe to HeapObjectSideTable of a. so, (*a2) = (objc*)object
70 | */
71 |
72 |
73 | // class: NSObject
74 | // +-----------------------------------------------------------------------+
75 | // | var isa: objc_class* -------------+
76 | // |- - - - - - - - - - - - - - - - - | |
77 | // | var property0: String | |
78 | // | var property1: [Int] | |
79 | // | . | |
80 | // | . | |
81 | // | . | |
82 | // +-----------------------------------------------------------------------+ |
83 | // |
84 | // |
85 | // +---------------------------------------------------------------+
86 | // |
87 | // V
88 | // isa (64 bits)
89 | // 0000000000000000000000000000000000000000000000000000000000000000
90 | // | ||||| || ||||
91 | // | ||||| || ||||
92 | // | ||||| || ||||
93 | // \ / ||| \ / \ / |||
94 | // extra_rc||| magic objc_class* |||
95 | // V|| V||
96 | // side_table|| has_cxx_dtor||
97 | // || ||
98 | // V| V|
99 | // deallocating| has_assoc|
100 | // | |
101 | // V V
102 | // weakly_referenced nonpointer
103 |
104 | /* NSObject:
105 |
106 | if extra_rc > 0xff || objc has weak ref { <--------------+
107 | use SideTable and set side_table bit = 1 |
108 | } |
109 | |
110 | static GlobalSideTables = Dictionary.init(bucketCount: 8) // iOS |
111 | |
112 | strct SideTable { |
113 | var lock: spinlock_t |
114 | |
115 | /* Int: 0 bit => objc has weak ref --------------------------------------------+
116 | Int: 1 bit => objc isDeallocating
117 | Int: 2~62 bits => count of extra_rc
118 | Int: 63 bit => ???
119 | */
120 | var refcnts: Dictionary
121 | var weak_table: Dictionary
122 | }
123 |
124 | struct weak_entry {
125 | var _objc: NSObject
126 |
127 | /* if weak_variables.count > 4
128 | weak_variables[0] become pointer and pointe to [&objc]
129 | weak_variables[1] = count of weak_variables
130 | */
131 | var weak_variables: [&objc].init(count: 4)
132 | }
133 |
134 |
135 | Refcnt:
136 | GlobalSideTables[objc].refcnts[objc]
137 |
138 | WeakEntry:
139 | GlobalSideTables[objc].weak_table[objc]
140 | */
141 |
142 |
143 | // MARK: - Swift Class
144 | /* unsafeBitCast is inlinable. enter unsafeBitCast, objc will retain 1. finish unsafeBitCast, objc will release 1.
145 | yout can use at debug, but not use at release
146 | */
147 |
148 | public func StrongRefCount(_ objc: T) -> UInt32 {
149 | assertNotNSObject(objc)
150 |
151 | func getStrongRefCount(bitsValue: UInt64) -> UInt32 {
152 | var mask: UInt64 = 1 << 30 - 1 // 30 bits => 111...111
153 | mask <<= 33 // 63 bits => 111...111000...000
154 | return UInt32((bitsValue & mask) >> 33) + 1 // The strong RC is stored as an extra count, so +1
155 | }
156 |
157 | if hasWeakRefCount(objc) {
158 | let bitsValue = getSileTablePointer(objc)?.pointee.bits.1
159 | return getStrongRefCount(bitsValue: UInt64(bitsValue!))
160 | } else {
161 | let objcPointer = unsafeBitCast(objc, to: UnsafeMutablePointer.self)
162 | let bitsValue = objcPointer.advanced(by: 1).pointee
163 | return getStrongRefCount(bitsValue: bitsValue)
164 | }
165 | }
166 |
167 | public func UnownedRefCount(_ objc: T) -> UInt32 {
168 | assertNotNSObject(objc)
169 |
170 | func getUnownedRefCount(bitsValue: UInt64) -> UInt32 {
171 | var mask: UInt64 = 1 << 31 - 1 // 31 bits => 111...111
172 | mask <<= 1 // 32 bits => 111...110
173 | return UInt32((bitsValue & mask) >> 1) - 1 // The unowned RC also has an extra +1 on behalf of the strong references; this +1 is decremented after deinit completes(Apple)
174 | }
175 |
176 | if hasWeakRefCount(objc) {
177 | let bitsValue = getSileTablePointer(objc)?.pointee.bits.1
178 | return getUnownedRefCount(bitsValue: UInt64(bitsValue!))
179 | } else {
180 | let objcPointer = unsafeBitCast(objc, to: UnsafeMutablePointer.self)
181 | let bitsValue = objcPointer.advanced(by: 1).pointee
182 | return getUnownedRefCount(bitsValue: bitsValue)
183 | }
184 | }
185 |
186 | // nil: has not weak reference
187 | public func WeakRefCount(_ objc: T) -> UInt32? {
188 | assertNotNSObject(objc)
189 |
190 | if hasWeakRefCount(objc), let sileTable = getSileTablePointer(objc) {
191 | return sileTable.pointee.weakBits - 1 // The weak RC also has an extra +1, this +1 is decremented after the object's allocation is freed(Apple)
192 | }
193 |
194 | return nil
195 | }
196 |
197 |
198 | // MARK: - Helper
199 |
200 | // useSlowValue && !isImmortalValue
201 | public func hasWeakRefCount(_ objc: T) -> Bool {
202 | assertNotNSObject(objc)
203 |
204 | let objcPointer = unsafeBitCast(objc, to: UnsafeMutablePointer.self)
205 | let bitsValue = objcPointer.advanced(by: 1).pointee
206 |
207 | let isImmortalMask: UInt64 = 1
208 | let isImmortalValue = bitsValue & isImmortalMask
209 |
210 | let useSlowMask: UInt64 = 1 << 63
211 | let useSlowValue = (bitsValue & useSlowMask) >> 63
212 |
213 | return (useSlowValue == 1) && (isImmortalValue != 1)
214 | }
215 |
216 | private func assertNotNSObject(_ objc: T) { // where T != NSObject
217 | assert(!(objc is NSObject), "NSObject's instace has not refCount property, look up it at runtime.objc")
218 | }
219 |
220 | private func getSileTablePointer(_ objc: T) -> UnsafeMutablePointer? {
221 | assertNotNSObject(objc)
222 | assert(hasWeakRefCount(objc))
223 |
224 | let objcPointer = unsafeBitCast(objc, to: UnsafeMutablePointer.self)
225 | let bitsValue = objcPointer.advanced(by: 1).pointee
226 | let mask: UInt64 = 1 << 62 - 1 // 62 bits => 111...111
227 | let slieTableValue = bitsValue & mask
228 | return UnsafeMutableRawPointer(bitPattern: UInt(slieTableValue << 3))?.assumingMemoryBound(to: HeapObjectSideTableEntry.self)
229 | }
230 |
231 | private struct HeapObjectSideTableEntry {
232 | let object: UnsafeMutableRawPointer
233 | let bits: (UInt64, Int64)
234 | let weakBits: UInt32
235 | }
236 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A93E5B64230262FC00DFC61A /* Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = A93E5B63230262FC00DFC61A /* Tuple.swift */; };
11 | A947489422FACE8F00212E57 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = A947489322FACE8F00212E57 /* main.swift */; };
12 | A94748A722FACE9F00212E57 /* Protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A947489B22FACE9F00212E57 /* Protocol.swift */; };
13 | A94748A822FACE9F00212E57 /* Class.swift in Sources */ = {isa = PBXBuildFile; fileRef = A947489C22FACE9F00212E57 /* Class.swift */; };
14 | A94748A922FACE9F00212E57 /* Enum.swift in Sources */ = {isa = PBXBuildFile; fileRef = A947489D22FACE9F00212E57 /* Enum.swift */; };
15 | A94748AA22FACE9F00212E57 /* Struct.swift in Sources */ = {isa = PBXBuildFile; fileRef = A947489E22FACE9F00212E57 /* Struct.swift */; };
16 | A94748AB22FACE9F00212E57 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A022FACE9F00212E57 /* Array.swift */; };
17 | A94748AC22FACE9F00212E57 /* Character.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A122FACE9F00212E57 /* Character.swift */; };
18 | A94748AD22FACE9F00212E57 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A222FACE9F00212E57 /* Dictionary.swift */; };
19 | A94748AE22FACE9F00212E57 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A322FACE9F00212E57 /* String.swift */; };
20 | A94748AF22FACE9F00212E57 /* Bool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A422FACE9F00212E57 /* Bool.swift */; };
21 | A94748B022FACE9F00212E57 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A522FACE9F00212E57 /* Optional.swift */; };
22 | A94748B122FACE9F00212E57 /* Set.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94748A622FACE9F00212E57 /* Set.swift */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | A947488E22FACE8F00212E57 /* CopyFiles */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = /usr/share/man/man1/;
30 | dstSubfolderSpec = 0;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 1;
34 | };
35 | /* End PBXCopyFilesBuildPhase section */
36 |
37 | /* Begin PBXFileReference section */
38 | A93E5B63230262FC00DFC61A /* Tuple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tuple.swift; sourceTree = ""; };
39 | A947489022FACE8F00212E57 /* SwiftDemo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwiftDemo; sourceTree = BUILT_PRODUCTS_DIR; };
40 | A947489322FACE8F00212E57 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
41 | A947489B22FACE9F00212E57 /* Protocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Protocol.swift; sourceTree = ""; };
42 | A947489C22FACE9F00212E57 /* Class.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Class.swift; sourceTree = ""; };
43 | A947489D22FACE9F00212E57 /* Enum.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enum.swift; sourceTree = ""; };
44 | A947489E22FACE9F00212E57 /* Struct.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Struct.swift; sourceTree = ""; };
45 | A94748A022FACE9F00212E57 /* Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = ""; };
46 | A94748A122FACE9F00212E57 /* Character.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Character.swift; sourceTree = ""; };
47 | A94748A222FACE9F00212E57 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = ""; };
48 | A94748A322FACE9F00212E57 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; };
49 | A94748A422FACE9F00212E57 /* Bool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bool.swift; sourceTree = ""; };
50 | A94748A522FACE9F00212E57 /* Optional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = ""; };
51 | A94748A622FACE9F00212E57 /* Set.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Set.swift; sourceTree = ""; };
52 | /* End PBXFileReference section */
53 |
54 | /* Begin PBXFrameworksBuildPhase section */
55 | A947488D22FACE8F00212E57 /* Frameworks */ = {
56 | isa = PBXFrameworksBuildPhase;
57 | buildActionMask = 2147483647;
58 | files = (
59 | );
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | /* End PBXFrameworksBuildPhase section */
63 |
64 | /* Begin PBXGroup section */
65 | A947488722FACE8F00212E57 = {
66 | isa = PBXGroup;
67 | children = (
68 | A947489222FACE8F00212E57 /* SwiftDemo */,
69 | A947489122FACE8F00212E57 /* Products */,
70 | );
71 | sourceTree = "";
72 | };
73 | A947489122FACE8F00212E57 /* Products */ = {
74 | isa = PBXGroup;
75 | children = (
76 | A947489022FACE8F00212E57 /* SwiftDemo */,
77 | );
78 | name = Products;
79 | sourceTree = "";
80 | };
81 | A947489222FACE8F00212E57 /* SwiftDemo */ = {
82 | isa = PBXGroup;
83 | children = (
84 | A947489A22FACE9F00212E57 /* Swift */,
85 | A947489F22FACE9F00212E57 /* SwiftCore */,
86 | A947489322FACE8F00212E57 /* main.swift */,
87 | );
88 | path = SwiftDemo;
89 | sourceTree = "";
90 | };
91 | A947489A22FACE9F00212E57 /* Swift */ = {
92 | isa = PBXGroup;
93 | children = (
94 | A947489E22FACE9F00212E57 /* Struct.swift */,
95 | A93E5B63230262FC00DFC61A /* Tuple.swift */,
96 | A947489C22FACE9F00212E57 /* Class.swift */,
97 | A947489B22FACE9F00212E57 /* Protocol.swift */,
98 | A947489D22FACE9F00212E57 /* Enum.swift */,
99 | );
100 | name = Swift;
101 | path = ../../Swift;
102 | sourceTree = "";
103 | };
104 | A947489F22FACE9F00212E57 /* SwiftCore */ = {
105 | isa = PBXGroup;
106 | children = (
107 | A94748A422FACE9F00212E57 /* Bool.swift */,
108 | A94748A522FACE9F00212E57 /* Optional.swift */,
109 | A94748A322FACE9F00212E57 /* String.swift */,
110 | A94748A122FACE9F00212E57 /* Character.swift */,
111 | A94748A022FACE9F00212E57 /* Array.swift */,
112 | A94748A222FACE9F00212E57 /* Dictionary.swift */,
113 | A94748A622FACE9F00212E57 /* Set.swift */,
114 | );
115 | name = SwiftCore;
116 | path = ../../SwiftCore;
117 | sourceTree = "";
118 | };
119 | /* End PBXGroup section */
120 |
121 | /* Begin PBXNativeTarget section */
122 | A947488F22FACE8F00212E57 /* SwiftDemo */ = {
123 | isa = PBXNativeTarget;
124 | buildConfigurationList = A947489722FACE8F00212E57 /* Build configuration list for PBXNativeTarget "SwiftDemo" */;
125 | buildPhases = (
126 | A947488C22FACE8F00212E57 /* Sources */,
127 | A947488D22FACE8F00212E57 /* Frameworks */,
128 | A947488E22FACE8F00212E57 /* CopyFiles */,
129 | );
130 | buildRules = (
131 | );
132 | dependencies = (
133 | );
134 | name = SwiftDemo;
135 | productName = SwiftDemo;
136 | productReference = A947489022FACE8F00212E57 /* SwiftDemo */;
137 | productType = "com.apple.product-type.tool";
138 | };
139 | /* End PBXNativeTarget section */
140 |
141 | /* Begin PBXProject section */
142 | A947488822FACE8F00212E57 /* Project object */ = {
143 | isa = PBXProject;
144 | attributes = {
145 | LastSwiftUpdateCheck = 1020;
146 | LastUpgradeCheck = 1020;
147 | ORGANIZATIONNAME = jintao;
148 | TargetAttributes = {
149 | A947488F22FACE8F00212E57 = {
150 | CreatedOnToolsVersion = 10.2.1;
151 | };
152 | };
153 | };
154 | buildConfigurationList = A947488B22FACE8F00212E57 /* Build configuration list for PBXProject "SwiftDemo" */;
155 | compatibilityVersion = "Xcode 9.3";
156 | developmentRegion = en;
157 | hasScannedForEncodings = 0;
158 | knownRegions = (
159 | en,
160 | );
161 | mainGroup = A947488722FACE8F00212E57;
162 | productRefGroup = A947489122FACE8F00212E57 /* Products */;
163 | projectDirPath = "";
164 | projectRoot = "";
165 | targets = (
166 | A947488F22FACE8F00212E57 /* SwiftDemo */,
167 | );
168 | };
169 | /* End PBXProject section */
170 |
171 | /* Begin PBXSourcesBuildPhase section */
172 | A947488C22FACE8F00212E57 /* Sources */ = {
173 | isa = PBXSourcesBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | A94748A822FACE9F00212E57 /* Class.swift in Sources */,
177 | A94748B022FACE9F00212E57 /* Optional.swift in Sources */,
178 | A94748AD22FACE9F00212E57 /* Dictionary.swift in Sources */,
179 | A947489422FACE8F00212E57 /* main.swift in Sources */,
180 | A94748AF22FACE9F00212E57 /* Bool.swift in Sources */,
181 | A94748AE22FACE9F00212E57 /* String.swift in Sources */,
182 | A94748AC22FACE9F00212E57 /* Character.swift in Sources */,
183 | A93E5B64230262FC00DFC61A /* Tuple.swift in Sources */,
184 | A94748A922FACE9F00212E57 /* Enum.swift in Sources */,
185 | A94748B122FACE9F00212E57 /* Set.swift in Sources */,
186 | A94748AB22FACE9F00212E57 /* Array.swift in Sources */,
187 | A94748AA22FACE9F00212E57 /* Struct.swift in Sources */,
188 | A94748A722FACE9F00212E57 /* Protocol.swift in Sources */,
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | /* End PBXSourcesBuildPhase section */
193 |
194 | /* Begin XCBuildConfiguration section */
195 | A947489522FACE8F00212E57 /* Debug */ = {
196 | isa = XCBuildConfiguration;
197 | buildSettings = {
198 | ALWAYS_SEARCH_USER_PATHS = NO;
199 | CLANG_ANALYZER_NONNULL = YES;
200 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
201 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
202 | CLANG_CXX_LIBRARY = "libc++";
203 | CLANG_ENABLE_MODULES = YES;
204 | CLANG_ENABLE_OBJC_ARC = YES;
205 | CLANG_ENABLE_OBJC_WEAK = YES;
206 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
207 | CLANG_WARN_BOOL_CONVERSION = YES;
208 | CLANG_WARN_COMMA = YES;
209 | CLANG_WARN_CONSTANT_CONVERSION = YES;
210 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
211 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
212 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
213 | CLANG_WARN_EMPTY_BODY = YES;
214 | CLANG_WARN_ENUM_CONVERSION = YES;
215 | CLANG_WARN_INFINITE_RECURSION = YES;
216 | CLANG_WARN_INT_CONVERSION = YES;
217 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
218 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
219 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
220 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
221 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
222 | CLANG_WARN_STRICT_PROTOTYPES = YES;
223 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
224 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
225 | CLANG_WARN_UNREACHABLE_CODE = YES;
226 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
227 | CODE_SIGN_IDENTITY = "Mac Developer";
228 | COPY_PHASE_STRIP = NO;
229 | DEBUG_INFORMATION_FORMAT = dwarf;
230 | ENABLE_STRICT_OBJC_MSGSEND = YES;
231 | ENABLE_TESTABILITY = YES;
232 | GCC_C_LANGUAGE_STANDARD = gnu11;
233 | GCC_DYNAMIC_NO_PIC = NO;
234 | GCC_NO_COMMON_BLOCKS = YES;
235 | GCC_OPTIMIZATION_LEVEL = 0;
236 | GCC_PREPROCESSOR_DEFINITIONS = (
237 | "DEBUG=1",
238 | "$(inherited)",
239 | );
240 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
241 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
242 | GCC_WARN_UNDECLARED_SELECTOR = YES;
243 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
244 | GCC_WARN_UNUSED_FUNCTION = YES;
245 | GCC_WARN_UNUSED_VARIABLE = YES;
246 | MACOSX_DEPLOYMENT_TARGET = 10.14;
247 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
248 | MTL_FAST_MATH = YES;
249 | ONLY_ACTIVE_ARCH = YES;
250 | SDKROOT = macosx;
251 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
252 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
253 | };
254 | name = Debug;
255 | };
256 | A947489622FACE8F00212E57 /* Release */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ALWAYS_SEARCH_USER_PATHS = NO;
260 | CLANG_ANALYZER_NONNULL = YES;
261 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
263 | CLANG_CXX_LIBRARY = "libc++";
264 | CLANG_ENABLE_MODULES = YES;
265 | CLANG_ENABLE_OBJC_ARC = YES;
266 | CLANG_ENABLE_OBJC_WEAK = YES;
267 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
268 | CLANG_WARN_BOOL_CONVERSION = YES;
269 | CLANG_WARN_COMMA = YES;
270 | CLANG_WARN_CONSTANT_CONVERSION = YES;
271 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
272 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
273 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
274 | CLANG_WARN_EMPTY_BODY = YES;
275 | CLANG_WARN_ENUM_CONVERSION = YES;
276 | CLANG_WARN_INFINITE_RECURSION = YES;
277 | CLANG_WARN_INT_CONVERSION = YES;
278 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
279 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
283 | CLANG_WARN_STRICT_PROTOTYPES = YES;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
286 | CLANG_WARN_UNREACHABLE_CODE = YES;
287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
288 | CODE_SIGN_IDENTITY = "Mac Developer";
289 | COPY_PHASE_STRIP = NO;
290 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
291 | ENABLE_NS_ASSERTIONS = NO;
292 | ENABLE_STRICT_OBJC_MSGSEND = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu11;
294 | GCC_NO_COMMON_BLOCKS = YES;
295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
297 | GCC_WARN_UNDECLARED_SELECTOR = YES;
298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
299 | GCC_WARN_UNUSED_FUNCTION = YES;
300 | GCC_WARN_UNUSED_VARIABLE = YES;
301 | MACOSX_DEPLOYMENT_TARGET = 10.14;
302 | MTL_ENABLE_DEBUG_INFO = NO;
303 | MTL_FAST_MATH = YES;
304 | SDKROOT = macosx;
305 | SWIFT_COMPILATION_MODE = wholemodule;
306 | SWIFT_OPTIMIZATION_LEVEL = "-O";
307 | };
308 | name = Release;
309 | };
310 | A947489822FACE8F00212E57 /* Debug */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | CODE_SIGN_STYLE = Automatic;
314 | DEVELOPMENT_TEAM = 8HX9UN9S6G;
315 | PRODUCT_NAME = "$(TARGET_NAME)";
316 | SWIFT_VERSION = 5.0;
317 | };
318 | name = Debug;
319 | };
320 | A947489922FACE8F00212E57 /* Release */ = {
321 | isa = XCBuildConfiguration;
322 | buildSettings = {
323 | CODE_SIGN_STYLE = Automatic;
324 | DEVELOPMENT_TEAM = 8HX9UN9S6G;
325 | PRODUCT_NAME = "$(TARGET_NAME)";
326 | SWIFT_VERSION = 5.0;
327 | };
328 | name = Release;
329 | };
330 | /* End XCBuildConfiguration section */
331 |
332 | /* Begin XCConfigurationList section */
333 | A947488B22FACE8F00212E57 /* Build configuration list for PBXProject "SwiftDemo" */ = {
334 | isa = XCConfigurationList;
335 | buildConfigurations = (
336 | A947489522FACE8F00212E57 /* Debug */,
337 | A947489622FACE8F00212E57 /* Release */,
338 | );
339 | defaultConfigurationIsVisible = 0;
340 | defaultConfigurationName = Release;
341 | };
342 | A947489722FACE8F00212E57 /* Build configuration list for PBXNativeTarget "SwiftDemo" */ = {
343 | isa = XCConfigurationList;
344 | buildConfigurations = (
345 | A947489822FACE8F00212E57 /* Debug */,
346 | A947489922FACE8F00212E57 /* Release */,
347 | );
348 | defaultConfigurationIsVisible = 0;
349 | defaultConfigurationName = Release;
350 | };
351 | /* End XCConfigurationList section */
352 | };
353 | rootObject = A947488822FACE8F00212E57 /* Project object */;
354 | }
355 |
--------------------------------------------------------------------------------