问题描述
借助ARC,我只需将对象的所有强引用都设置为nil
即可对其进行分配.
With ARC, I can just set all of an object's strong references to nil
to deallocate it.
对于UnsafePointer
或UnsafeMutablePointer
,我需要显式管理其内存:
With an UnsafePointer
or UnsafeMutablePointer
, I need to manage its memory explicitly:
let buffer = sizeof(Int8) * 4
var ptr = UnsafeMutablePointer<Void>.alloc(buffer)
defer {
ptr.destroy()
ptr.dealloc(someVal)
ptr = nil
}
但是文档对于AutoreleasingUnsafeMutablePointer
对象是模棱两可的.我无法在AutoreleasingUnsafeMutablePointer
上显式调用destroy
或dealloc
.
But the documentation is ambiguous for AutoreleasingUnsafeMutablePointer
objects. I cannot explicitly call destroy
or dealloc
on a AutoreleasingUnsafeMutablePointer
.
var ptr: AutoreleasingUnsafeMutablePointer<Void> = nil
defer {
ptr = nil
}
// assign something to ptr
名称暗示它在超出范围后会自动发布,但是我是否需要将AutoreleasingUnsafeMutablePointer
设置为nil
才能使其自动发布?
The name implies that it is autoreleased after it falls out of scope, but do I need to set a AutoreleasingUnsafeMutablePointer
to nil
in order for it to be autoreleased?
这是一个示例,其中我使用AutoreleasingUnsafeMutablePointer
来获取运行时当前加载的所有类的列表.请注意,在调用Objective-C运行时的功能时,某些函数需要AutoreleasingUnsafeMutablePointer
而不是UnsafeMutablePointer
:
Here's an example where I use an AutoreleasingUnsafeMutablePointer
to get a list of all of the classes currently loaded by the runtime. Note that when invoking the power of the Objective-C runtime some functions require a AutoreleasingUnsafeMutablePointer
rather than just a UnsafeMutablePointer
:
var numClasses: Int32 = 0
var allClasses: AutoreleasingUnsafeMutablePointer<AnyClass?> = nil
defer {
allClasses = nil // is this required?
}
numClasses = objc_getClassList(nil, 0)
if numClasses > 0 {
var ptr = UnsafeMutablePointer<AnyClass>.alloc(Int(numClasses))
defer {
ptr.destroy()
ptr.dealloc(Int(numClasses))
ptr = nil
}
allClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>.init(ptr)
numClasses = objc_getClassList(allClasses, numClasses)
for i in 0 ..< numClasses {
if let currentClass: AnyClass = allClasses[Int(i)] {
print("\(currentClass)")
}
}
}
推荐答案
您无需将其设置为nil
.它应该由自动释放的指针构造(假设它构造正确,它将释放自己).同时,不要在当前堆栈帧之后停留. AutoreleasingUnsafeMutablePointer
不能使对象保持活动状态.弹出封闭的自动释放池时,被包装的对象将被释放并可能被释放.顾名思义,它是不安全.
You don't need to set it to nil
. It is supposed to be constructed from an autoreleased pointer (assuming it was constructed correctly, it will release itself). At the same time, don't hold onto it past the current stack frame. The AutoreleasingUnsafeMutablePointer
does not keep the object alive. When the enclosing autorelease pool is popped, the wrapped object will be released and probably deallocated. Like the name says: it is unsafe.
通过从不在Swift中创建自己的AutoreleasingUnsafeMutablePointer
来避免问题(编辑:除非它确实是UnsafeMutablePointer且C标头导入出错了,请参见下文).如果正确使用它,它应该是Swift的inout
和Objective-C指针返回参数之间的透明胶.
Avoid problems by never creating AutoreleasingUnsafeMutablePointer
yourself in Swift (edit: except when it's really an UnsafeMutablePointer and the C header import has made a mistake, see below). If you're using it correctly, it should be transparent glue between Swift's inout
and an Objective-C return-by-pointer parameter.
通常,您创建一个与所包含类型匹配的var
并将其传递给inout
.
You generally create a var
matching the contained type and pass it in by inout
.
例如如果要调用该函数:
e.g. if you want to call the function:
func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>)
然后您像这样调用它:
var myObject: AnyObject? = nil
someFunction(&AnyObject)
一切都会解决.
我不知道您应该按住AutoreleasingUnsafeMutablePointer
的任何其他情况.我认为除了nil
之外,您根本不应该在Swift端手动构建一个.在Swift中,构造具有非nil
内容的AutoreleasingUnsafeMutablePointer
非常困难,因为自动释放的唯一方法是使用Unmanaged
.
I'm not aware of any other situation where you should hold an AutoreleasingUnsafeMutablePointer
. I don't think you should be manually constructing one at all on the Swift side except as nil
. It is precariously difficult in Swift to construct an AutoreleasingUnsafeMutablePointer
with non-nil
contents since the only way to autorelease is using Unmanaged
.
正在响应您的更新...
objc_getClassList
函数签名是Swift自动C导入中的一个小故障.它错误地假定将Class *
参数导入为AutoreleasingUnsafeMutablePointer<AnyObject?>
.您实际上只需要一个UnsafeMutablePointer
即可从数组中获取:
The objc_getClassList
function signature is a glitch in Swift's automatic C importing. It incorrectly assumes that a Class *
parameter should be imported as AutoreleasingUnsafeMutablePointer<AnyObject?>
. You really just need an UnsafeMutablePointer
which you can get from an array:
var allClasses = Array<AnyClass?>(count: Int(objc_getClassList(nil, 0)), repeatedValue: nil)
allClasses.withUnsafeMutableBufferPointer { (inout bp: UnsafeMutableBufferPointer<AnyClass?>) in
objc_getClassList(AutoreleasingUnsafeMutablePointer(bp.baseAddress), Int32(allClasses.count))
}
这篇关于是否需要取消分配AutoreleasingUnsafeMutablePointer?如果是这样,怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!