Если функция возвращает UnsafeMutablePointer, это наша ответственность за уничтожение и dealloc?
Например, если бы я написал этот код:
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)")
... было бы также необходимо также сделать следующее?
x.destroy()
x.dealloc(1)
Или мы не выделили память и поэтому не нужно ее отклонять?
Обновление # 1:
Если мы представим функцию, которая возвращает UnsafeMutablePointer
:
func point() -> UnsafeMutablePointer<String> {
let a = UnsafeMutablePointer<String>.alloc(1)
a.initialize("Hello, world!")
return a
}
Вызов этой функции приведет к указателю на объект, который никогда не будет уничтожен, если мы сами не сделаем грязную работу.
Вопрос, который я задаю здесь: Является ли указатель, полученный от вызова localtime()
, другим?
Симулятор и игровая площадка позволяют нам отправить один вызов dealloc(1)
возвращенному указателю, но должны ли мы это делать или будет освобождение, которое произойдет для возвращаемого указателя каким-либо другим методом в более поздней точке?
В настоящий момент я ошибаюсь в предположении, что нам нужно уничтожить и dealloc.
Обновление # 1.1:
Последнее предположение было неправильным. Мне не нужно выпускать, потому что я не создавал объект.
Обновление # 2:
Я получил несколько ответов на тот же запрос на форумах Apple dev.
В общем, ответ на ваш вопрос - да. Если вы получите указатель на память, на который вы будете отвечать за освобождение на C, вы по-прежнему несете ответственность за освобождение его при вызове из быстрого... [Но] в этом конкретном случае вам ничего не нужно. (JQ)
сама процедура поддерживает статическую память для результата, и вам не нужно их освобождать. (возможно, это было бы "плохо", если бы вы это сделали)... В общем, вы не можете знать, нужно ли вам высвобождать то, на что указывает UnsafePointer.... это зависит от того, где этот указатель получает свое значение. (СТ)
UnsafePointer dealloc() несовместим со свободным(). Пара alloc() с dealloc() и malloc и co. со свободным(). Как указывалось ранее, функция, которую вы вызываете, должна сообщить вам, является ли ваш ответ свободным от результата... destroy() необходимо только в том случае, если у вас нетривиальный контент * в памяти, на которую указывает указатель, например сильная ссылка или структура или перечисление Swift. В общем, если он пришел из C, вам, вероятно, не нужно его уничтожать(). (На самом деле, вы, вероятно, не должны его уничтожать(), потому что он не был инициализирован Swift.)... * "нетривиальный контент" не является официальным термином Swift. Я использую его по аналогии с понятием С++ "тривиально скопируемым" (хотя и не обязательно "тривиальным" ). (СТЭ)
Окончательное обновление:
Теперь я написал blogpost, в котором излагаются мои выводы и предположения относительно выпуска небезопасных указателей, которые берут на борт информацию от StackOverflow, Apple Dev Forums, Twitter и старой документации Apple по распределению памяти и выпуску ее, до ARC. См. здесь.
Ответы
Ответ 1
Из библиотеки Swift UnsafeMutablePointer<T>
Указатель на объект типа T
. Этот тип не обеспечивает автоматизацию управления памятью, и поэтому пользователь должен позаботиться о том, чтобы выделить и свободной памяти соответственно.
Указатель может находиться в одном из следующих состояний:
- память не выделяется (например, указатель имеет значение null, или память имеет
ранее освобожден);
- выделена память, но значение не было инициализировано;
- выделена память и инициализируется значение.
struct UnsafeMutablePointer<T> : RandomAccessIndexType, Hashable, NilLiteralConvertible { /**/}