如何在C++Map中存储自动引用计数的Swift/Objective-C对象,而不会在从Map中删除它们时导致内存泄漏?

rvpgvaaj  于 2023-09-29  发布在  Swift
关注(0)|答案(1)|浏览(107)

我有一个CMap,它管理加载的区域。每个区域都有一个关联的MTLBuffer,用于在区域数据转换为网格后生成的几何图形。这个想法是在CMap中存储对每个缓冲区的引用,这样我就可以在一个数据结构中拥有所有的区域及其相关数据。我可以使用Objective-C++伪代码:

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[positon].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.
}

然而,当从Map中删除区域时,例如在这样的函数中:

void delete_region(uint16_t position) {
    Region *region = loaded_regions[position];

    // ...

    map.erase(position);
    delete position;
}

假设我启用了ARC,我如何确保任何存储的Swift对象引用或Objective-C对象引用都被正确释放,并且不会导致内存泄漏?
这是可能的吗?或者我只需要做一个Swift Dictionary或Objective-C NSDictionary来独立于存储动作区域的C++Map来存储这些缓冲区?
当ARC被启用时,Xcode将不允许直接使用release消息,所以我不知道如何手动释放内存。

6yoyoihd

6yoyoihd1#

这是很容易与智能指针。请参见下面的草图。

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]);

相关问题