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

问题描述 投票:0回答:1

我有一个管理加载区域的 C++ 映射。每个区域都有一个关联的

MTLBuffer
,用于区域数据转换为网格后生成的几何图形。这个想法是在 C++ 映射内存储对每个缓冲区的引用,以便我将所有区域及其关联数据存储在单个数据结构中。我可以得到这个 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.
}

但是,当从地图中删除区域时,例如在如下函数中:

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++ 映射来存储这些缓冲区?

启用ARC后,Xcode将不允许直接使用

release
消息,所以我不知道如何手动释放内存。

c++ swift objective-c memory-leaks automatic-ref-counting
1个回答
0
投票

使用智能指针非常容易。请参阅下面的草图。

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]);
© www.soinside.com 2019 - 2024. All rights reserved.