当我们调用 IUnknown::Release 时会发生什么

dev*_*roy 1 directx directx-11

例如,在以下代码中:

ID3D11Texture2D* texture2d; 

    HRESULT result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*) &texture2d);//mSwapChain is a swap chain, as obvious

    result = mDevice->CreateRenderTargetView(texture2d, 0, &mTargetView);

    texture2d->Release();
Run Code Online (Sandbox Code Playgroud)

我真的很困惑在调用 release 之后交换链中的后台缓冲区会发生什么。目前我认为可能发生的是,指针被释放,而不会影响后台缓冲区本身。不过,我需要一个更详细的答案,因为我很难理解这个概念。

jco*_*der 6

纹理对象维护它所拥有的“引用”数量的内部计数。最初,当您的代码启动时,交换链内部有一个指向纹理的指针,因此它的引用计数为 1。

当它返回一个指向您的指针时,现在有两个对该对象的引用。

请注意,swapchain::GetBuffer 内部的代码通过在将指针返回给您之前调用纹理的 AddRef 函数来手动执行此操作。

因此,当您调用 Release all 时,它会将引用计数减一,然后说“啊,仍然有一个引用,所以我什么都不做。”

如果交换链对象在您对纹理调用 Release 之前已被删除,则它会“释放”它对纹理的引用,因此当您调用 Release 时,它​​会将纹理的引用计数减少到零,它会说“啊,没人再利用我了,我自己删除!”。

所以基本上你在纹理上调用 Release 只是你告诉纹理你不再对它感兴趣。它仍然会留在记忆中,直到每个人都告诉它。