I have a C++ map which manages loaded regions. Each region has an associated MTLBuffer
for the geometry generated after the region data is converted into a mesh. The idea is to store a reference to each buffer inside the C++ map so I have all of the regions and their associated data in a single data structure. I could have this Objective-C++ pseudocode:
struct Region {
void *buffer;
// Other fields
};
std::unordered_map<uint64_t, Region> loaded_regions;
void render_region(Region *region) {
float vertices[MAX_SIZE];
unsigned length;
// ...
// There are multiple ways I could do this. One could be:
map[position].buffer = [device newBufferWithBytes: vertices length: length options: MTLStorageModeShared];
// I could also pass `vertices` to some external function defined in Swift that creates a new `MTLBuffer` and returns it.
// This is then converted to a bare pointer and stored in the map.
}
However, when regions are deleted from the map, for example in a function like this:
void delete_region(uint16_t position) {
Region *region = loaded_regions[position];
// ...
map.erase(position);
delete position;
}
How can I ensure any stored Swift object references or Objective-C object references are properly released and no memory leak is caused, assuming I have ARC enabled?
Is this possible, or will I just have to make a Swift Dictionary
or an Objective-C NSDictionary
to store these buffers independently from the C++ map that stores the actual regions?
When ARC is enabled, Xcode will not allow release
messages to be used directly, so I do not know how else to manually free the memory.
It's quite easy with smart pointers. See the sketch below.
struct Deleter {
void operator()(void *buffer) const nothrow { CFRelease(buffer); }
};
struct Region {
std::unique_ptr<void, Deleter> buffer;
// Other fields
};
map[positon].buffer.reset([device newBufferWithBytes:vertices
length:length
options:MTLStorageModeShared]);