2016-07-04 16 views
6

Jestem trochę zdezorientowany. Kiedy muszę dzwonić za darmo i kiedy niszczyć/dealloc? Pracuję nad krótkim rdzeniem nauki kodu źródłowego. Pomyślałem, że jeśli zadzwonię pod numer UnsafeMutablePointer<Type>.alloc(size), powinienem zadzwonić pod numer destroy & dealloc. Ale jeśli używam malloc() lub calloc(), powinienem zadzwonić pod numer free().Jak obsługiwać UnsafeMutablePointer poprawnie

W tym przykładzie od nauki Core Audio następujący fragment kodu sprawia, że ​​zastanawiam się:

var asbds = UnsafeMutablePointer<AudioStreamBasicDescription>.alloc(Int(infoSize)) 
audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat, 
           UInt32(sizeof(fileTypeAndFormat.dynamicType)), &fileTypeAndFormat, 
           &infoSize, asbds) 

Tutaj używam alloc. Aby zwolnić pamięć, wywoływana jest nazwa free.

free(asbds) 

Ale dlaczego nie

asbds.destroy(Int(infoSize)) 
asbds.dealloc(Int(infoSize)) 

której bym się spodziewał po regule.

Byłbym wdzięczny za każdą pomoc, ponieważ to sprawia, że ​​moja głowa się kręci. Dokumentacja mówi, że jestem odpowiedzialny za zniszczenie i dealloc, aby część była jasna, ale w jaki sposób?

Odpowiedz

1

Zobacz UnsafeMutablePointer Structure Reference.

Wskaźnik może być w jednym z następujących stanów:

  • pamięci nie jest alokowana (na przykład, wskaźnik ma wartość null, lub pamięć została dealokowane wcześniej).

  • Pamięć jest alokowana, ale wartość nie została zainicjalizowana.

  • Pamięć jest przydzielana i inicjowana jest wartość.

Można użyć zaostrzonym obszarze bezpiecznie, gdy „przydzielane i inicjalizowane”. Tak więc, jeśli chcesz poprawnie używać Swift UnsafeMutablePointer, potrzebujesz 2 kroków przed użyciem i 2 kroków po użyciu.

(1) Przydziel: alloc(_:).

(2) Initilize: initialize...()

Można bezpiecznie używać tutaj przydzieloną i zainicjowany region.

(3) Deinitialize: destroy(_:)

(4) Deallocate: dealloc(_:)


I dlaczego można użyć free() dla alloc(_:) pamięci ED, to dlatego, że Swift wykorzystuje malloc(_:) w bieżącej realizacji alloc(_:). Używanie bezpłatnego oznacza, że ​​twoja aplikacja zależy od aktualnej implementacji środowiska wykonawczego Swift.


Używanie UnsafeMutablePointer jest więc trudne i denerwujące. Należy rozważyć przekazanie tablicy jako wskaźnika. W twoim przypadku można napisać coś takiego:

let elementCount = Int(infoSize)/strideof(AudioStreamBasicDescription) 
    var asbds: [AudioStreamBasicDescription] = Array(count: elementCount, repeatedValue: AudioStreamBasicDescription()) 
    audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat, 
            UInt32(sizeof(fileTypeAndFormat.dynamicType)), &fileTypeAndFormat, 
            &infoSize, &asbds) 

(.. Myślę, że należy skorzystać z tej elementCount nawet przy użyciu UnsafeMutablePointeralloc(_:) lub dealloc(_:) używa „liczbę elementów”, a nie „rozmiar bajtów”)

+0

Dziękuję bardzo. To bardzo pomogło. Bardzo podoba mi się podejście do tablicy, które sprawia, że ​​rzeczy stają się bardziej szybkie. Ale żeby uzyskać część 'free()' wyczyszczoną dla mnie. W tej chwili nie ma żadnej różnicy w nazywaniu "free" lub "destroy" i "dealloc"? Czy rozumiem, że to prawda? Ponieważ 'alloc' nazywa' malloc' za zasłonami. – enovatia

Powiązane problemy