本文介绍了是否需要取消分配AutoreleasingUnsafeMutablePointer?如果是这样,怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

借助ARC,我只需将对象的所有强引用都设置为nil即可对其进行分配.

With ARC, I can just set all of an object's strong references to nil to deallocate it.

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

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

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?如果是这样,怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 20:56