问题
/// Destroy the object the pointer points to.
///
/// Precondition: the memory is initialized.
///
/// Postcondition: the value has been destroyed and the memory must
/// be initialized before being used again.
func destroy()
What do the terms object
, memory
and value
mean in this context?
回答1:
When doing low-level programming where you manage the memory yourself instead of having a language runtime handle it for you, using memory is a two-stage process.
First, you allocate a region of memory. This just reserves some chunk of raw space, it doesn’t set the memory to have any particular value. The memory could contain random garbage, or it could contain some data that was previously in that location of memory. You should never rely on this region of memory having any particular value.
Then you initialize it, by setting that area of memory to some well-defined value. Maybe you set it to all zeroes. Maybe you divide it up into chunks and treat those chunks as separate variables held inside the memory. Maybe you copy some data from somewhere else.
If you are using a high-level language like Swift, you probably want to set up the memory to represent an object – a collection of member variables and other supporting data. This collection of data is structured in a very specific way, so that you can pass it as a particular object type to other functions, and call member methods on it. To set the object up, you would call it’s “init” method that sets the member variables appropriately.
Here, setting the memory to have a “value” and creating an “object” in the memory are similar concepts, but the term “object” implies operating at a higher level of abstraction.
When you’re done with your object, you go through the same steps in reverse. First, you might do the “high-level” operation of calling the object’s de-initialization code. For example, calling the deinit()
method of a class, or releasing references to other objects.
At this point, the memory is still allocated to you but it’s back to being considered “garbage” that you mustn’t look at. But you still need to “deallocate” the memory (give it back) to return to the state you started at. Or, you could choose not to, instead re-using the raw memory and creating a new object in-place.
UnsafeMutablePointer
helps you through this process, by making it easy to allocate and deallocate memory, but more important, helps you safely create objects in that memory, and has lots of helper methods for moving around control of that memory, initializing from different kinds of source data etc.
Here’s an example:
class MyClass {
init() { println("created") }
deinit { println("destroyed") }
}
struct MyStruct {
let i: Int
let d: Double
let c: MyClass
}
// allocate enough memory for 1 MyStruct object
// (you can also allocate enough memory for several objects)
var aStruct = UnsafeMutablePointer<MyStruct>.alloc(1)
// no MyStruct has been created yet – we’ve just allocated
// enough memory to hold one
// set that memory to represent a new MyStruct object
aStruct.initialize(MyStruct(i: 4, d: 2.2, c: MyClass()))
println("Memory contains a MyStruct with i = \(aStruct.memory.i)")
// should see the class print "destroyed"
aStruct.destroy()
// at this point, "memory" should be conisidered rubbish
// reinitialize it with something new:
aStruct.initialize(MyStruct(i: 8, d: 3.3, c: MyClass()))
println("Memory contains a MyStruct with i = \(aStruct.memory.i)")
// should see the class print "destroyed"
aStruct.destroy()
// finally, deallocate the raw memory
aStruct.dealloc(1)
Obviously, with a name like UnsafeMutablePointer
, it can still be dangerous to use if you don’t know what you’re doing. But it’s still a whole lot safer than accessing memory directly without this kind of helper.
来源:https://stackoverflow.com/questions/27670643/terminology-concerning-unsafemutablepointers-destroy