Is it necessary to free AutoreleasingUnsafeMutablePointer? If so, how?

With ARC, I can simply set nil links for all objects to free it.

Using UnsafePointer or UnsafeMutablePointer I need to explicitly manage my memory:

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

But the documentation is ambiguous for AutoreleasingUnsafeMutablePointer objects. I cannot explicitly call destroy or dealloc on AutoreleasingUnsafeMutablePointer .

 var ptr: AutoreleasingUnsafeMutablePointer<Void> = nil defer { ptr = nil } // assign something to ptr 

The name implies that it was auto-implemented after it fell out of scope, but do I need to set AutoreleasingUnsafeMutablePointer to nil so that it is auto-implemented?

Here is an example when I use AutoreleasingUnsafeMutablePointer to get a list of all the classes currently loading at runtime. Note that when calling power at runtime, Objective-C requires AutoreleasingUnsafeMutablePointer for some functions, not just 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)") } } } 
+6
source share
1 answer

You do not need to install it on nil . It is assumed that it will be built from an auto-implemented pointer (provided that it was built correctly, it will be freed). At the same time, do not hold onto it for the current stack stack. AutoreleasingUnsafeMutablePointer does not keep the object alive. When the closed pool of autoresists is opened, the wrapped object will be freed and probably freed. Like the name says: it is unsafe.

Avoid problems by never creating AutoreleasingUnsafeMutablePointer yourself in Swift ( edit ), unless it really is a UnsafeMutablePointer error and importing the C header made a mistake, see below). If you use it correctly, it should be a transparent glue between the Swift inout and the Objective-C return-by-pointer parameter.

Usually you create a var that matches the contained type and pass it to inout .

eg. if you want to call a function:

 func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>) 

then you call it like this:

 var myObject: AnyObject? = nil someFunction(&AnyObject) 

and everything will work.

I do not know of any other situation where you should keep AutoreleasingUnsafeMutablePointer . I don’t think you should manually create it on the Swift side other than nil . In Swift, it’s hard to create an AutoreleasingUnsafeMutablePointer construct with nil content, since the only way to auto- Unmanaged is to use Unmanaged .

Responding to your update ...

The functional signature of objc_getClassList is a failure in the automatic import of C. It incorrectly assumes that the Class * parameter should be imported as AutoreleasingUnsafeMutablePointer<AnyObject?> . You really need an UnsafeMutablePointer , which you can get from the 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)) } 
+5
source

All Articles