swift - Si una función devuelve un UnsafeMutablePointer, ¿es nuestra responsabilidad destruir y dealloc?
allocation destroy (1)
Por ejemplo si tuviera que escribir este código:
var t = time_t()
time(&t)
let x = localtime(&t) // returns UnsafeMutablePointer<tm>
println("/(x.memory.tm_hour): /(x.memory.tm_min): /(x.memory.tm_sec)")
... ¿también sería necesario hacer lo siguiente?
x.destroy()
x.dealloc(1)
¿O no asignamos la memoria y, por lo tanto, no necesitamos descartarla?
Actualización # 1:
Si imaginamos una función que devuelve un UnsafeMutablePointer
:
func point() -> UnsafeMutablePointer<String> {
let a = UnsafeMutablePointer<String>.alloc(1)
a.initialize("Hello, world!")
return a
}
Llamar a esta función resultaría en un puntero a un objeto que nunca será destruido a menos que nosotros hagamos el trabajo sucio.
La pregunta que hago aquí : ¿Se recibe un puntero de una llamada localtime()
diferente?
El simulador y el patio de recreo nos permiten enviar una dealloc(1)
al puntero devuelto, pero ¿deberíamos hacerlo o se va a realizar la desasignación para un puntero devuelto por algún otro método en un momento posterior?
En este momento me estoy equivocando en la suposición de que necesitamos destruir y dealloc.
Actualización # 1.1:
La última suposición fue errónea. No necesito liberar, porque no creé el objeto.
Actualización # 2:
Recibí algunas respuestas a la misma consulta en los foros de desarrollo de Apple.
En general, la respuesta a su pregunta es sí. Si recibe un puntero a la memoria que sería responsable de liberar en C, entonces todavía es responsable de liberarlo al llamar desde swift ... [Pero] en este caso particular, no necesita hacer nada. (JQ)
la rutina en sí misma mantiene la memoria estática para el resultado y no es necesario liberarlos. (probablemente sería "algo malo" si lo hiciera) ... En general, no puede saber si necesita liberar algo apuntado por un UnsafePointer ... depende de dónde el puntero obtiene su valor. (S T)
Dealloc () de UnsafePointer no es compatible con free (). Par de alloc () con dealloc () y malloc and co. Con free (). Como se señaló anteriormente, la función que está llamando debería decirle si es su respuesta para liberar el resultado ... destroy () solo es necesario si tiene contenido * no trivial en la memoria a la que hace referencia el puntero, como una referencia fuerte o una estructura Swift o enumeración. En general, si proviene de C, es probable que no necesite destruirlo (). (De hecho, probablemente no deberías destruirlo) porque Swift no lo inicializó.) ... * "contenido no trivial" no es un término oficial de Swift. Lo estoy usando por analogía con la noción de C ++ de "copiable de forma trivial" (aunque no necesariamente "trivial"). (STE)
Actualización final:
Ahora he escrito una entrada de blog que describe mis hallazgos y suposiciones con respecto al lanzamiento de punteros inseguros que contienen información a bordo de StackOverflow, Apple Dev Forums, Twitter y la documentación anterior de Apple sobre la asignación de memoria y la publicación, pre-ARC. Ver here
De la biblioteca Swift UnsafeMutablePointer<T>
Un puntero a un objeto de tipo
T
Este tipo no proporciona administración de memoria automatizada y, por lo tanto, el usuario debe ocuparse de asignar y liberar la memoria de manera apropiada .
El puntero puede estar en uno de los siguientes estados:
- la memoria no está asignada (por ejemplo, el puntero es nulo o la memoria se ha desasignado previamente);
- la memoria está asignada, pero el valor no se ha inicializado;
- Se asigna memoria y se inicializa el valor.
struct UnsafeMutablePointer<T> : RandomAccessIndexType, Hashable, NilLiteralConvertible { /**/}