是否有必要取消分配 AutoreleasingUnsafeMutablePointer?如果是这样,如何?

Is it necessary to deallocate an AutoreleasingUnsafeMutablePointer? If so, how?

使用 ARC,我可以将对象的所有强引用设置为 nil 以释放它。

对于 UnsafePointerUnsafeMutablePointer,我需要显式管理其内存:

let buffer = sizeof(Int8) * 4
var ptr = UnsafeMutablePointer<Void>.alloc(buffer)
defer {
    ptr.destroy()
    ptr.dealloc(someVal)
    ptr = nil
}

但是 AutoreleasingUnsafeMutablePointer 对象的文档不明确。我不能在 AutoreleasingUnsafeMutablePointer.

上显式调用 destroydealloc
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))
}