1

我关于 Stackoverflow 的第一个问题。

让我从一些代码开始。这有点重复,所以我将剪掉我为不同阵列重复的部分(请随意询问其他部分)。但是,请忽略代码而不是回答底部的问题。首先:提前感谢回答者。第二:数据的释放。

@implementation ES1Renderer

GLfloat **helixVertices;
GLushort **helixIndices;
GLubyte **helixColors;

- (void)freeEverything
{
    if (helixVertices != NULL)
    {
        for (int i=0; i < alphasToFree / 30 + 1; i++)
            free(helixVertices[i]);
        free(helixVertices);
    }

    if (helixIndices != NULL)
    {
        for (int i=0; i < alphasToFree / 30 + 1; i++)
            free(helixIndices[i]);
        free(helixIndices);
    }

    if (helixColors != NULL)
    {
        for (int i=0; i < alphasToFree / 30 + 1; i++)
            free(helixColors[i]);
        free(helixColors);
    }
}

(我稍后会谈到这个问题)。现在对于我 malloc() 数组的位置。

- (void)askForVertexInformation
{
    int nrows = self.helper.numberOfAtoms / 300;
    int mrows = [self.helper.bonds count] / 300;

    int alphaCarbonRows = [self.helper.alphaCarbons count] / 30;

    helixVertices = malloc(alphaCarbonRows * sizeof(GLfloat *) + 1);
    helixIndices = malloc(alphaCarbonRows * sizeof(GLfloat *) + 1);
    helixColors = malloc(alphaCarbonRows * sizeof(GLfloat *) + 1);

    for (int i=0; i < alphaCarbonRows + 1; i++)
    {
        helixVertices[i] = malloc(sizeof(helixVertices) * HELIX_VERTEX_COUNT * 3 * 33);
        helixIndices[i] = malloc(sizeof(helixIndices) * HELIX_INDEX_COUNT * 2 * 3 * 33);
        helixColors[i] = malloc(sizeof(helixColors) * HELIX_VERTEX_COUNT * 4 * 33);

    }
    [self.helper recolourVerticesInAtomRange:NSMakeRange(0, [self.helper.alphaCarbons count]) withColouringType:CMolColouringTypeCartoonBlue forMasterColorArray:helixColors forNumberOfVertices:HELIX_VERTEX_COUNT difference:30]; 

    self.atomsToFree = self.helper.numberOfAtoms;
    self.bondsToFree = [self.helper.bonds count];
    self.alphasToFree = [self.helper.alphaCarbons count];
}

最后,调用一切的位(这是一个单独的类。)

- (void)loadPDB:(NSString *)pdbToLoad
{
    if (!self.loading)
    {
        [self performSelectorOnMainThread:@selector(stopAnimation) withObject:nil waitUntilDone:YES];
        [self.renderer freeEverything];
        [renderer release];
        ES1Renderer *newRenderer = [[ES1Renderer alloc] init];
        renderer = [newRenderer retain];
        [self performSelectorOnMainThread:@selector(stopAnimation) withObject:nil waitUntilDone:YES]; // need to stop the new renderer animating too!
        [self.renderer setDelegate:self];
        [self.renderer setupCamera];
        self.renderer.pdb = nil;
        [renderer resizeFromLayer:(CAEAGLLayer*)self.layer];
        [newRenderer release];

        NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(setup:) object:pdbToLoad];
        [self.queue addOperation:invocationOperation];
        [invocationOperation release];
    }
}

- (void)setup:(NSString *)pdbToLoad
{
    self.loading = YES;

    [helper release];
    [renderer.helper release];
    PDBHelper *aHelper = [[PDBHelper alloc] initWithContentsOfFile:pdbToLoad];
    helper = [aHelper retain];
    renderer.helper = [aHelper retain];
    [aHelper release];

    if (!resized)
    {
        [self.helper resizeVertices:11];
        resized = YES;
    }

    self.renderer.helper = self.helper;

    [self.helper setUpAtoms];
    [self.helper setUpBonds];

    if (self.helper.numberOfAtoms > 0)
        [self.renderer askForVertexInformation];
    else
    {           
        // LOG ME PLEASE.
    }

    [self performSelectorOnMainThread:@selector(removeProgressBar) withObject:nil waitUntilDone:YES];
    [self performSelectorOnMainThread:@selector(startAnimation) withObject:nil waitUntilDone:YES];
    self.renderer.pdb = pdbToLoad;

    self.loading = NO;
}

我在这里所做的是将 PDB 文件中的分子加载到内存中,并将其显示在 OpenGL 视图窗口中。第二次加载一个分子(它将在loadPDB:上面运行)时,我得到了大三角综合症和相关影响......我会在我的分子上看到大三角形。

但是,每次加载新分子时,我都会释放并重新分配我的 PDBHelper 和 ES1Renderer。因此我想知道:

1. 我声明为类范围变量的 helixVertices、helixIndices 和 helixColors 是否在这个实例中实际被重用。它们指向相同的对象吗?
2. 我应该在释放后将所有变量设置为 NULL 吗?无论如何,我打算这样做,通过获得一个段错误来发现任何错误,但还没有来得及合并它。3. 我对 malloc() 一个类变量是否正确?有没有更好的方法来实现这一目标?否则,我没有其他已知方式将此信息提供给渲染器。

4

1 回答 1

1

我无法回答你的一般性问题。里面东西太多了 然而,这引起了我的注意:

[helper release];
[renderer.helper release];
PDBHelper *aHelper = [[PDBHelper alloc] initWithContentsOfFile:pdbToLoad];
helper = [aHelper retain];
renderer.helper = [aHelper retain];
[aHelper release];

我认为这东西可能会泄漏。无论如何这没有意义。

如果 renderer.helper 是一个保留或复制属性,请不要释放它。它已经有代码在分配新值时释放旧值。也不要保留您分配给它的对象。

你已经分配了一个助手,所以没有必要再次保留它。上面的代码应该重写如下:

[helper release];
helper = [[PDBHelper alloc] initWithContentsOfFile:pdbToLoad];
renderer.helper = helper;

另外,我认为您的螺旋分配数组可能应该是实例变量。就目前情况而言,如果您有多个 ES1Renderer,它们将共享这些变量。

于 2010-07-29T08:16:40.090 回答