Slide 1

Slide 1 text

Swift’s
 Pointy Bits

Slide 2

Slide 2 text

Unsafe
 Pointer
 Types

Slide 3

Slide 3 text

Unsafe

Slide 4

Slide 4 text

“Safe”

Slide 5

Slide 5 text

let ages = [13.3, 17.5, 18.9, 21.2]

Slide 6

Slide 6 text

let ages = [13.3, 17.5, 18.9, 21.2] let firstPlusOne = ages.first + 1

Slide 7

Slide 7 text

let ages = [13.3, 17.5, 18.9, 21.2] let firstPlusOne = ages.first + 1 Value of optional type ‘Int?’ not unwrapped; did you mean to use ‘!’ or ‘?’

Slide 8

Slide 8 text

let ages = [13.3, 17.5, 18.9, 21.2] let firstPlusOne = ages.first! + 1 // firstPlusOne = 14.3

Slide 9

Slide 9 text

let ages: [Double] = [] let firstPlusOne = ages.first! + 1

Slide 10

Slide 10 text

let ages: [Double] = [] let firstPlusOne = ages.first! + 1 ! error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=

Slide 11

Slide 11 text

let ages = [13.3, 17.5, 18.9, 21.2] let average = ages.reduce(0, +) /
 Double(ages.count) // average = 17.725

Slide 12

Slide 12 text

let ages: [Double] = [] let average = ages.reduce(0, +) /
 Double(ages.count)

Slide 13

Slide 13 text

let ages: [Double] = [] let average = ages.reduce(0, +) / 0

Slide 14

Slide 14 text

let ages: [Double] = [] let average = ages.reduce(0, +) / 0 ! error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code= ed: This doesn’t actually crash, but would for [Int]

Slide 15

Slide 15 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4]

Slide 16

Slide 16 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4] // off by one

Slide 17

Slide 17 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4] // off by one error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code= !

Slide 18

Slide 18 text

“Safe”

Slide 19

Slide 19 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4] // off by one

Slide 20

Slide 20 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4] // off by one // sure, fine, whatever

Slide 21

Slide 21 text

let ages = [13.3, 17.5, 18.9, 21.2] let last = ages[4] // off by one // last == ???

Slide 22

Slide 22 text

Unexpected Behavior

Slide 23

Slide 23 text

10110001 10000001 11001111 00011000 10001110 00010110 00100100 00000000 10110001 10000001 11001111 00011000 10001110 00010110 00100100 00000000 01101000 00001010 10000001 10100110 00010000 01101000 00001010 00000001 10101010 10101010 10101010 10101010 10101010 10101010 10101010 00001010 00000101 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111000 00100111 11101111 00010100 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01111010 00000000 01100001 00000000 01110000 00000000 00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01101100 01101111 01100001 01100100 00100000 01100110 01110010 01101111 01101101 00100000 01101101 01101001 01110011 01100001 01101100 01101001 01100111 01101110 01100101 01100100 00100000 01110010 01100001 01110111 00100000 01110000 01101111 01101001 01101110 01110100 01100101 01110010 00000000 01100110 01100001 01110100 01100001 01101100 00100000 01100101 01110010 01110010 01101111 01110010 00000000 00000000 00000000 00000000 01101001 01101110 01110110 01100001 01101100 01101001 01100100 00100000 01110101 01101110 01110011 01100001 01100110 01100101 01000100 01101111 01110111 01101110 01100011 01100001 01110011 01110100 00000000 00000000

Slide 24

Slide 24 text

B1 81 CF 18 8E 16 24 00 B1 81 CF 18 8E 16 24 00 68 0A 81 A6 10 68 0A 01 AA AA AA AA AA AA AA 0A 05 00 00 00 00 00 00 00 18 18 4F 12 01 00 00 00 00 00 00 00 00 00 00 00 7A 00 61 00 70 00 20 00 00 00 00 00 00 00 00 00 6C 6F 61 64 20 66 72 6F 6D 20 6D 69 73 61 6C 69 67 6E 65 64 20 72 61 77 20 70 6F 69 6E 74 65 72 00 66 61 74 61 6C 20 65 72 72 6F 72 00 00 00 00 69 6E 76 61 6C 69 64 20 75 6E 73 61 66 65 44 6F 77 6E 63 61 73 74 00 00

Slide 25

Slide 25 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 88982D1401000000 0000000000000000 C0922D1401000000 0000000000000000 C0922D1401000000 0000000000000000 7A00610070000030 7800200000000000 756E657870656374 65646C7920666F75 6E64206E696C2077 68696C6520756E77 72617070696E6720

Slide 26

Slide 26 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 88982D1401000000 0000000000000000 C0922D1401000000 0000000000000000 C0922D1401000000 0000000000000000 7A00610070000030 7800200000000000 756E657870656374 65646C7920666F75 6E64206E696C2077 68696C6520756E77 72617070696E6720 0x9868 0x9870 0x9878 0x9880 0x9888 0x9890 0x9898 0x98A0 0x98A8 0x98B0 0x98B8 0x98C0 0x98C8 0x98D0 0x98D8 0x98E0 0x98E8 0x98F0

Slide 27

Slide 27 text

var age = 5 B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 88982D1401000000 0000000000000000 C0922D1401000000 0000000000000000 C0922D1401000000 0000000000000000 7A00610070000030 7800200000000000 756E657870656374 65646C7920666F75 6E64206E696C2077 68696C6520756E77 72617070696E6720 0x9868 0x9870 0x9878 0x9880 0x9888 0x9890 0x9898 0x98A0 0x98A8 0x98B0 0x98B8 0x98C0 0x98C8 0x98D0 0x98D8 0x98E0 0x98E8 0x98F0

Slide 28

Slide 28 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 88982D1401000000 0000000000000000 C0922D1401000000 0000000000000000 C0922D1401000000 0000000000000000 7A00610070000030 7800200000000000 756E657870656374 65646C7920666F75 6E64206E696C2077 68696C6520756E77 72617070696E6720 0x9868 0x9870 0x9878 0x9880 0x9888 0x9890 0x9898 0x98A0 0x98A8 0x98B0 0x98B8 0x98C0 0x98C8 0x98D0 0x98D8 0x98E0 0x98E8 0x98F0 var age = 5

Slide 29

Slide 29 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 0x9868 0x9870 0x9878 0x9880 0x9888 var age = 5 withUnsafePointer(to: &age) { // ... }

Slide 30

Slide 30 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 0x9868 0x9870 0x9878 0x9880 0x9888 var age = 5 withUnsafePointer(to: &age) { agePointer in // ... }

Slide 31

Slide 31 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 0x9868 0x9870 0x9878 0x9880 0x9888 var age = 5 withUnsafePointer(to: &age) { agePointer in print(agePointer.pointee) } > 5

Slide 32

Slide 32 text

Unsafe
 Pointer
 Types

Slide 33

Slide 33 text

UnsafePointer UnsafeMutablePointer UnsafeRawPointer UnsafeMutableRawPointer

Slide 34

Slide 34 text

UnsafePointer UnsafeMutablePointer UnsafeRawPointer UnsafeMutableRawPointer Typed

Slide 35

Slide 35 text

UnsafePointer UnsafeMutablePointer UnsafeRawPointer UnsafeMutableRawPointer B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 88982D1401000000 0000000000000000 C0922D1401000000 0000000000000000 C0922D1401000000 0000000000000000 7A00610070000030 7800200000000000 756E657870656374 65646C7920666F75 6E64206E696C2077 68696C6520756E77 72617070696E6720 0x9868 0x9870 0x9878 0x9880 0x9888 0x9890 0x9898 0x98A0 0x98A8 0x98B0 0x98B8 0x98C0 0x98C8 0x98D0 0x98D8 0x98E0 0x98E8 0x98F0

Slide 36

Slide 36 text

UnsafePointer UnsafeMutablePointer UnsafeRawPointer UnsafeMutableRawPointer Raw

Slide 37

Slide 37 text

UnsafePointer UnsafeMutablePointer UnsafeRawPointer UnsafeMutableRawPointer

Slide 38

Slide 38 text

UnsafeMutablePointer UnsafeMutableRawPointer UnsafePointer UnsafeRawPointer Immutable

Slide 39

Slide 39 text

UnsafeMutablePointer UnsafeMutableRawPointer Mutable

Slide 40

Slide 40 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 0x9868 0x9870 0x9878 0x9880 0x9888 var age = 5 withUnsafeBytes(of: &age) { // ... }

Slide 41

Slide 41 text

B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A 0500000000000000 0x9868 0x9870 0x9878 0x9880 0x9888 var age = 5 withUnsafeBytes(of: &age) { ageBytes in ageBytes.count // 8 ageBytes.first // Optional(5) ageBytes[0] // 5 }

Slide 42

Slide 42 text

var age = 2000 withUnsafeBytes(of: &age) { ageBytes in ageBytes.count // 8 ageBytes.first // Optional(208) ageBytes[0] // 208 } B181CF188E162400 B181CF188E162400 680A81A610680A01 AAAAAAAAAAAAAA0A D007000000000000 0x9868 0x9870 0x9878 0x9880 0x9888

Slide 43

Slide 43 text

Imported C APIs Speed

Slide 44

Slide 44 text

func SKSearchFindMatches( _ inMaximumCount: CFIndex, _ outIDsArray: UnsafeMutablePointer!, _ outFoundCount: UnsafeMutablePointer! ) -> Bool

Slide 45

Slide 45 text

let limit = 100 var foundCount = 0 as CFIndex var documentIDs = Array(repeating: 0 as SKDocumentID, count: limit) _ = SKSearchFindMatches(CFIndex(limit), &documentIDs, &foundCount) for i in 0..

Slide 46

Slide 46 text

let limit = 100 var foundCount = 0 as CFIndex var documentIDs = Array(repeating: 0 as SKDocumentID, count: limit) _ = SKSearchFindMatches(CFIndex(limit), &documentIDs, &foundCount) for i in 0..

Slide 47

Slide 47 text

let limit = 100 var foundCount = 0 as CFIndex var documentIDs: [SKDocumentID] = [] documentIDs.reserveCapacity(limit) _ = SKSearchFindMatches(CFIndex(limit), &documentIDs, &foundCount) for i in 0..

Slide 48

Slide 48 text

let limit = 100 var foundCount = 0 as CFIndex var documentIDs = Array(repeating: 0 as SKDocumentID, count: limit) _ = SKSearchFindMatches(CFIndex(limit), &documentIDs, &foundCount) for i in 0..

Slide 49

Slide 49 text

let limit = 100 var foundCount = 0 as CFIndex let documentIDs = UnsafeMutablePointer .allocate(capacity: limit) defer { documentIDs.deallocate(capacity: limit) } _ = SKSearchFindMatches(CFIndex(limit), documentIDs, &foundCount) for i in 0..

Slide 50

Slide 50 text

let limit = 100 var foundCount = 0 as CFIndex let documentIDs = UnsafeMutablePointer .allocate(capacity: limit) defer { documentIDs.deallocate(capacity: limit) } _ = SKSearchFindMatches(CFIndex(limit), documentIDs, &foundCount) for i in 0..

Slide 51

Slide 51 text

func bubbleSort(_ array: inout [T]) { guard !array.isEmpty else { return } for n in 1.. array[i] { swap(&array[i - 1], &array[i]) } } } }

Slide 52

Slide 52 text

func bubbleSort(_ array: inout [T]) { guard !array.isEmpty else { return } array.withUnsafeMutableBufferPointer { buffer in for n in 1.. buffer[i] { swap(&buffer[i - 1], &buffer[i]) } } } } }

Slide 53

Slide 53 text

Really Not Safe at All

Slide 54

Slide 54 text

var age = 2000 let agePointer = UnsafeMutablePointer(&age) agePointer.pointee = 10 // age == 10

Slide 55

Slide 55 text

var age = 2000 let agePointer = withUnsafeMutablePointer(to: &age) { p in return p } agePointer.pointee = 10 // age == 10

Slide 56

Slide 56 text

var age = 2000 let agePointer = UnsafeMutablePointer(&age) agePointer.pointee = 10 // age == 10 undefined
 behavior

Slide 57

Slide 57 text

Swift’s Pointy Bits Nate Cook @nnnnnnnn