1

我目前正在编写代码以从 NSView 获取 OpenGL 纹理。该代码主要是 Apple 示例代码。但是,我需要在 C++ 类中使用它,并且我遇到了泄漏对象的问题。

这是代码中有趣的部分:

GLuint CPlusPlusClass::openGLTexFromNSView(NSView* theView)
{
    GLuint texName = 0x0;

    @autoreleasepool // 1
    {  // 1
        NSBitmapImageRep* bitmap = [theView bitmapImageRepForCachingDisplayInRect:[theView visibleRect]];

        int samplesPerPixel = 0;
        [theView cacheDisplayInRect:[theView visibleRect] toBitmapImageRep:bitmap];

        samplesPerPixel = (int)[bitmap samplesPerPixel];

        glPixelStorei(GL_UNPACK_ROW_LENGTH, (int)([bitmap bytesPerRow]/samplesPerPixel));
        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

        glGenTextures (1, &texName);

        glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texName);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        if(![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4))
        {
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                         samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
                         (int)[bitmap pixelsWide], (int)[bitmap pixelsHigh],
                         0, samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
                         GL_UNSIGNED_BYTE, [bitmap bitmapData]);
        }
    } // 1
    return texName;
}

当我将视图绘制到 OpenGL 上下文并在 Activity Monitor 中检查应用程序的内存占用时,我看到每次 Activity Monitor 的视图刷新时该数字都会增加约 4 MB。通过添加代码中@autoreleasepool指示的块//1,我可以将它降低到每个刷新周期大约 2 MB。尽管如此,它仍在不断增加。

从 C++ 中释放自动释放对象的正确方法是什么?

4

2 回答 2

4

那不是C++,它是Objective-C++

间接回答了这个问题;您在 Objective-C++ 中管理 Objective-C 对象的方式与在直接的 Objective-C 中完全一样。

对于手动滚动线程,您需要手动管理自动释放池。确保在线程中第一次调用 Objective-C 之前有一个池,并确保它在线程退出之前被耗尽。如果线程寿命很长,那么您将需要定期创建和排出自动释放池(就像它们自动在运行循环中一样)。

于 2013-08-19T16:54:23.913 回答
0

事实证明,我正在做的事情@autoreleasepool是绝对正确的。

我上面概述的函数每秒调用大约 50-60 次。我发现增加的内存负载是由重复调用glGenTextures. 它应该存储在一个变量中,而不是每次都被覆盖。

我不认为这有问题。以为是自动释放池相关...

于 2013-08-19T19:01:25.780 回答