Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Copy-on-Write в Swift

CocoaHeads
October 31, 2017
450

Copy-on-Write в Swift

CocoaHeads

October 31, 2017
Tweet

More Decks by CocoaHeads

Transcript

  1. ArraySlice & Substring 8 let fib = [0, 1, 1,

    2, 3, 5, 8, 13, 21, 34, 55] let lessTen = fib[..<8] // not copying Не выделяет новой памяти под массив • Не выделяется память до мутирования • Такой же интерфейс • Указывает на первоначальный массив с представлением • Это круто
  2. ArraySlice & Substring 9 let greeting = "Hi there! Nice

    to meet you! " let endOfSentence = greeting.index(of: "!")! let firstSentence = greeting[...endOfSentence] • Не выделяется память до мутирования • Такой же интерфейс • Указывает на первоначальную строку с представлением • Это круто
  3. WTF? 14 • Повышение привилегий ❌ • Возникает состояние “гонки”

    за маловероятную ситуацию • Несколько секунд ⏰ • С другими эксплойтами можно удаленно сделать хак
  4. In Swift 17 let string1 = “Cocoa” var string2 =

    string1 // Copied string2 += "Heads" // mutating to 'CocoaHeads'
  5. In Swift 18 let string1 = “Cocoa” var string2 =

    string1 // Copied string2 += "Heads" // mutating to ‘CocoaHeads’ print("\(string1) \(string2)") // 'Cocoa CocoaHeads'
  6. In Swift 19 let string1 = “Cocoa” var string2 =

    string1 // Copied string2 += "Heads" // mutating to ‘CocoaHeads’ print("\(string1) \(string2)") // 'Cocoa CocoaHeads' Arrays?
  7. CoW in Swift 22 var array1 = [1, 2, 3]

    // 0x60400007ca20 var array2 = array1 // 0x60400007ca20
  8. CoW in Swift 23 var array1 = [1, 2, 3]

    // 0x60400007ca20 var array2 = array1 // 0x60400007ca20 array2.append(4) // 0x6000000830e0 Буфер
  9. CoW in Swift 24 var array1 = [1, 2, 3]

    // 0x60400007ca20 var array2 = array1 // 0x60400007ca20 array2.append(4) // 0x6000000830e0 var arrayCopy = array1 as [Any] // 0x60000012ade0 А еще, если мы попробуем преобразовать, то адрес также поменяется
  10. Задача 28 Реализовать структуру, которая не будет обладать свойствами класса.

    Будет копироваться не сразу, а когда будет изменяться.
  11. Manual CoW 31 final class Reference<T> { var value: T

    init(value: T) { self.value = value } } 2
  12. Manual CoW 33 struct Box<T> { private var ref: Reference<T>

    init(_ value: T) { ref = Reference(value: value) } ….. 3.1
  13. Manual CoW 34 …. var value: T { get {

    return ref.value } } } 3.2
  14. Manual CoW 35 …. var value: T { get {

    return ref.value } set { guard isKnownUniquelyReferenced(&ref) else { ref = Reference(value: newValue) return } ref.value = newValue } } } 3.2
  15. isKnownUniquelyReferenced(_:) 36 Data A B False Data A True nil

    A False strong strong strong Data A B False weak unowned weak unowned
  16. When true? 37 • Single strong reference • With single

    some weak/unowned • Race condition
  17. Manual CoW 38 …. var value: T { get {

    return ref.value } set { guard isKnownUniquelyReferenced(&ref) else { ref = Reference(value: newValue) return } ref.value = newValue } } } 3.2
  18. Using 42 let serverData = // Getting server data var

    box1 = Box(serverData) var box2 = box1 // shares box1.ref
  19. Using 43 let serverData = // Getting server data var

    box1 = Box(serverData) var box2 = box1 // shares box1.ref box2.value.articles.removeFirst() // creates box2.ref