使用ARC,我可以设置对象的所有强引用nil
来解除分配。
使用UnsafePointer
或UnsafeMutablePointer
,我需要明确管理其内存:
let buffer = sizeof(Int8) * 4
var ptr = UnsafeMutablePointer<Void>.alloc(buffer)
defer {
ptr.destroy()
ptr.dealloc(someVal)
ptr = nil
}
但AutoreleasingUnsafeMutablePointer
对象的文档含糊不清。我无法在destroy
上明确呼叫dealloc
或AutoreleasingUnsafeMutablePointer
。
var ptr: AutoreleasingUnsafeMutablePointer<Void> = nil
defer {
ptr = nil
}
// assign something to ptr
该名称暗示它在超出范围后自动释放,但我是否需要将AutoreleasingUnsafeMutablePointer
设置为nil
才能自动释放?
这是一个示例,我使用AutoreleasingUnsafeMutablePointer
来获取运行时当前加载的所有类的列表。请注意,在调用Objective-C运行时的强大功能时,某些函数需要AutoreleasingUnsafeMutablePointer
而不仅仅是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)")
}
}
}
答案 0 :(得分:6)
您不需要将其设置为nil
。它应该由一个自动释放的指针构造(假设它被正确构造,它将自行释放)。同时,不要超过当前的堆栈框架。 AutoreleasingUnsafeMutablePointer
不会使对象保持活动状态。弹出封闭的自动释放池时,将释放包装的对象并可能已取消分配。就像名字所说:它是不安全的。
通过永远不在Swift中创建AutoreleasingUnsafeMutablePointer
来避免出现问题(编辑:除非它真的是一个UnsafeMutablePointer并且C标头导入出错了,见下文)。如果您正确使用它,它应该是Swift的inout
和Objective-C返回指针参数之间的透明胶水。
您通常会创建与所包含类型匹配的var
,并将其传递给inout
。
e.g。如果你想调用这个函数:
func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>)
然后你这样调用它:
var myObject: AnyObject? = nil
someFunction(&AnyObject)
一切都会成功。
我不知道你应该持有AutoreleasingUnsafeMutablePointer
的任何其他情况。除了作为nil
之外,我不认为你应该在Swift一侧手动构建一个。由于自动释放的唯一方法是使用AutoreleasingUnsafeMutablePointer
,因此在Swift中构建具有非nil
内容的Unmanaged
是非常困难的。
回复您的更新...
objc_getClassList
函数签名是Swift自动C导入的一个小故障。它错误地假定Class *
参数应导入为AutoreleasingUnsafeMutablePointer<AnyObject?>
。你真的需要一个UnsafeMutablePointer
,你可以从一个数组中获得:
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))
}