2016-07-04 83 views
6

Sono un po 'confuso. Quando devo chiamare gratis e quando distruggi/dealloc? Sto lavorando ad uno snippet di codice breve per imparare l'audio di base. Ho pensato di chiamare lo UnsafeMutablePointer<Type>.alloc(size), quindi chiamare lo destroy & dealloc. Ma se uso malloc() o calloc() dovrei chiamare free().Come gestire correttamente UnsafeMutablePointer

In questo esempio da Learning Core Audio il seguente frammento di codice mi domando:

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

Qui io uso alloc. Per liberare memoria si chiama free.

free(asbds) 

Ma perché non

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

che mi aspetterei seguendo la regola.

Apprezzerei qualsiasi aiuto, perché questo mi fa girare la testa. La documentazione dice che sono responsabile della distruzione e dealloc in modo che la parte sia chiara, ma in che modo?

risposta

1

Vedere UnsafeMutablePointer Structure Reference.

Il puntatore può essere in uno dei seguenti stati:

  • memoria non si alloca (per esempio, il puntatore è nullo, o memoria è stata precedentemente deallocato).

  • La memoria è allocata, ma il valore non è stato inizializzato.

  • La memoria è allocata e il valore è inizializzato.

È possibile utilizzare la regione punta in modo sicuro quando "allocata e inizializzata". Quindi, se si desidera utilizzare correttamente lo UnsafeMutablePointer di Swift, sono necessari 2 passaggi prima dell'uso e 2 passaggi dopo l'uso.

(1) Assegnazione: alloc(_:).

(2) Initilize: initialize...()

È possibile utilizzare in modo sicuro la regione allocata e inizializzata qui.

(3) Deinitialize: destroy(_:)

(4) Dealloca: dealloc(_:)


E perché si può usare free() per alloc(_:) di memoria ed, è perché Swift utilizza malloc(_:) nell'implementazione corrente di alloc(_:). Quindi, utilizzare gratuitamente significa che l'app dipende dall'attuale implementazione del runtime di Swift.


Quindi, utilizzando UnsafeMutablePointer è una sorta di difficile e fastidioso. Dovresti considerare di passare un array come un puntatore. Nel tuo caso, è possibile scrivere qualcosa di simile:

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) 

(.. Credo che si dovrebbe utilizzare questo elementCount anche quando si utilizza UnsafeMutablePointeralloc(_:) o dealloc(_:) usa "numero di elementi", non "dimensione in byte")

+0

Grazie mille. Questo ha aiutato molto. Mi piace molto l'approccio dell'array, che rende le cose molto più veloci. Ma per ottenere la parte 'libera()' chiarita per me. In questo momento non vi è alcuna differenza nel chiamare 'free'or' destroy'and 'dealloc'? Ho capito bene? Perché 'alloc' sta chiamando' malloc' dietro le quinte. – enovatia