是否有必要取消分配 AutoreleasingUnsafeMutablePointer?如果是这样,如何?
Is it necessary to deallocate an AutoreleasingUnsafeMutablePointer? If so, how?
使用 ARC,我可以将对象的所有强引用设置为 nil
以释放它。
对于 UnsafePointer
或 UnsafeMutablePointer
,我需要显式管理其内存:
let buffer = sizeof(Int8) * 4
var ptr = UnsafeMutablePointer<Void>.alloc(buffer)
defer {
ptr.destroy()
ptr.dealloc(someVal)
ptr = nil
}
但是 AutoreleasingUnsafeMutablePointer
对象的文档不明确。我不能在 AutoreleasingUnsafeMutablePointer
.
上显式调用 destroy
或 dealloc
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)")
}
}
}
您不需要将其设置为nil
。它应该是从一个自动释放的指针构造的(假设它构造正确,它将自行释放)。同时,不要在当前堆栈帧之后继续保留它。 AutoreleasingUnsafeMutablePointer
不会使对象保持活动状态。当封闭的自动释放池弹出时,包装的对象将被释放并可能被释放。顾名思义:不安全.
避免在 Swift 中自己创建 AutoreleasingUnsafeMutablePointer
(编辑:除非它确实是一个 UnsafeMutablePointer 并且 C 头文件导入出错, 见下文)。如果你正确使用它,它应该是 Swift 的 inout
和 Objective-C return-by-pointer 参数之间的透明胶水。
您通常会创建一个 var
匹配包含的类型并通过 inout
将其传入。
例如如果你想调用函数:
func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>)
然后你像这样调用它:
var myObject: AnyObject? = nil
someFunction(&AnyObject)
一切都会好起来的。
我不知道您应该持有 AutoreleasingUnsafeMutablePointer
的任何其他情况。我不认为你应该在 Swift 端手动构建一个,除了 nil
。在 Swift 中构建具有非 nil
内容的 AutoreleasingUnsafeMutablePointer
非常困难,因为自动释放的唯一方法是使用 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))
}
使用 ARC,我可以将对象的所有强引用设置为 nil
以释放它。
对于 UnsafePointer
或 UnsafeMutablePointer
,我需要显式管理其内存:
let buffer = sizeof(Int8) * 4
var ptr = UnsafeMutablePointer<Void>.alloc(buffer)
defer {
ptr.destroy()
ptr.dealloc(someVal)
ptr = nil
}
但是 AutoreleasingUnsafeMutablePointer
对象的文档不明确。我不能在 AutoreleasingUnsafeMutablePointer
.
destroy
或 dealloc
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)")
}
}
}
您不需要将其设置为nil
。它应该是从一个自动释放的指针构造的(假设它构造正确,它将自行释放)。同时,不要在当前堆栈帧之后继续保留它。 AutoreleasingUnsafeMutablePointer
不会使对象保持活动状态。当封闭的自动释放池弹出时,包装的对象将被释放并可能被释放。顾名思义:不安全.
避免在 Swift 中自己创建 AutoreleasingUnsafeMutablePointer
(编辑:除非它确实是一个 UnsafeMutablePointer 并且 C 头文件导入出错, 见下文)。如果你正确使用它,它应该是 Swift 的 inout
和 Objective-C return-by-pointer 参数之间的透明胶水。
您通常会创建一个 var
匹配包含的类型并通过 inout
将其传入。
例如如果你想调用函数:
func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>)
然后你像这样调用它:
var myObject: AnyObject? = nil
someFunction(&AnyObject)
一切都会好起来的。
我不知道您应该持有 AutoreleasingUnsafeMutablePointer
的任何其他情况。我不认为你应该在 Swift 端手动构建一个,除了 nil
。在 Swift 中构建具有非 nil
内容的 AutoreleasingUnsafeMutablePointer
非常困难,因为自动释放的唯一方法是使用 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))
}