Swift Language
(Niebezpieczne) Wskaźniki bufora
Szukaj…
Wprowadzenie
„Wskaźnik bufora służy do niskiego poziomu dostępu do regionu pamięci. Na przykład możesz użyć wskaźnika bufora do skutecznego przetwarzania i komunikacji danych między aplikacjami i usługami. ”
Fragment: Apple Inc. „Używanie Swift z kakao i Objective-C (wydanie Swift 3.1)”. iBooks. https://itun.es/us/utTW7.l
Odpowiadasz za obsługę cyklu życia pamięci, z którą pracujesz, za pomocą wskaźników bufora, aby uniknąć wycieków lub nieokreślonego zachowania.
Uwagi
Niezbędne są ściśle dopasowane koncepcje do pełnego zrozumienia (Niebezpiecznych) BufferPointers.
- MemoryLayout ( układ pamięci typu, opisujący jego rozmiar, krok i wyrównanie ).
- Niezarządzany ( typ do propagowania odwołania do niezarządzanego obiektu ).
- UnsafeBufferPointer ( nie będący właścicielem interfejs kolekcji do bufora elementów przechowywanych w pamięci w sposób ciągły ).
- UnsafeBufferPointerIterator ( iterator dla elementów w buforze, do których odwołuje się instancja UnsafeBufferPointer lub UnsafeMutableBufferPointer ).
- UnsafeMutableBufferPointer ( nie będący właścicielem interfejs kolekcji do bufora zmiennych elementów przechowywanych w pamięci ).
- UnsafeMutablePointer ( wskaźnik do uzyskiwania dostępu do danych określonego typu i manipulowania nimi ).
- UnsafeMutableRawBufferPointer ( Zmienny nieposiadający interfejs kolekcji do bajtów w regionie pamięci ).
- UnsafeMutableRawBufferPointer.Iterator ( Iterator nad bajtami oglądany przez surowy wskaźnik bufora ).
- UnsafeMutableRawPointer ( surowy wskaźnik do uzyskiwania dostępu i manipulowania nietypowymi danymi ).
- UnsafePointer ( wskaźnik dostępu do danych określonego typu ).
- UnsafeRawBufferPointer ( nieposiadający interfejsu kolekcji bajtów w regionie pamięci ).
- UnsafeRawBufferPointer.Iterator ( iterator nad bajtami oglądany przez surowy wskaźnik bufora ).
- UnsafeRawPointer ( nieprzetworzony wskaźnik dostępu do nietypowych danych ).
(Źródło, Swiftdoc.org )
UnsafeMutablePointer
struct UnsafeMutablePointer<Pointee>
Wskaźnik do uzyskiwania dostępu do danych określonego typu i manipulowania nimi.
Wystąpienia typu UnsafeMutablePointer służą do uzyskiwania dostępu do danych określonego typu w pamięci. Typ danych, do których wskaźnik może uzyskać dostęp, to typ Pointee wskaźnika. UnsafeMutablePointer nie zapewnia automatycznego zarządzania pamięcią ani gwarancji wyrównania. Odpowiadasz za obsługę cyklu życia pamięci, z którą pracujesz, poprzez niebezpieczne wskaźniki, aby uniknąć wycieków lub nieokreślonego zachowania.
Pamięć, którą zarządzasz ręcznie, może być albo bez typu, albo powiązana z określonym typem. Typ UnsafeMutablePointer służy do uzyskiwania dostępu do pamięci powiązanej z określonym typem i zarządzania nią. ( Źródło )
import Foundation
let arr = [1,5,7,8]
let pointer = UnsafeMutablePointer<[Int]>.allocate(capacity: 4)
pointer.initialize(to: arr)
let x = pointer.pointee[3]
print(x)
pointer.deinitialize()
pointer.deallocate(capacity: 4)
class A {
var x: String?
convenience init (_ x: String) {
self.init()
self.x = x
}
func description() -> String {
return x ?? ""
}
}
let arr2 = [A("OK"), A("OK 2")]
let pointer2 = UnsafeMutablePointer<[A]>.allocate(capacity: 2)
pointer2.initialize(to: arr2)
pointer2.pointee
let y = pointer2.pointee[1]
print(y)
pointer2.deinitialize()
pointer2.deallocate(capacity: 2)
Konwersja do Swift 3.0 z oryginalnego źródła
Praktyczne zastosowanie dla wskaźników buforowych
Dekonstruowanie użycia niebezpiecznego wskaźnika w metodzie biblioteki Swift;
public init?(validatingUTF8 cString: UnsafePointer<CChar>)
Cel, powód:
Tworzy nowy ciąg, kopiując i sprawdzając dane UTF-8 zakończone znakiem null, do których odwołuje się dany wskaźnik.
Ten inicjator nie próbuje naprawić źle sformułowanych sekwencji jednostek kodu UTF-8. Jeśli jakieś zostaną znalezione, wynik inicjalizatora wynosi nil
. Poniższy przykład wywołuje ten inicjator ze wskaźnikami do zawartości dwóch różnych tablic CChar
--- pierwsza z dobrze uformowanymi sekwencjami jednostek kodu UTF-8, a druga z źle uformowaną sekwencją na końcu.
Źródło , Apple Inc., plik nagłówka Swift 3 (Aby uzyskać dostęp do nagłówka: W Playground, Cmd + kliknij słowo Swift) w wierszu kodu:
import Swift
let validUTF8: [CChar] = [67, 97, 102, -61, -87, 0]
validUTF8.withUnsafeBufferPointer { ptr in
let s = String(validatingUTF8: ptr.baseAddress!)
print(s as Any)
}
// Prints "Optional(Café)"
let invalidUTF8: [CChar] = [67, 97, 102, -61, 0]
invalidUTF8.withUnsafeBufferPointer { ptr in
let s = String(validatingUTF8: ptr.baseAddress!)
print(s as Any)
}
// Prints "nil"
(Źródło, Apple Inc., przykład pliku Swift Header)