【问题标题】:Objective-c Opengl memory leakObjective-c OpenGL 内存泄漏
【发布时间】:2014-03-02 19:57:13
【问题描述】:

在将许多图像分配给单个变量时,我的 iOS 应用程序出现内存泄漏。

我的更新功能的简化版本,但仍然证明了这一点。

每秒调用 10 次。我需要在渲染后释放分配,但我不知道该怎么做。

- (void) update
{
PSSprite * score1sDigit = [[PSSprite alloc] initWithFile:[NSString stringWithFormat:@"#%i.png", score%10] effect:self.effect];
}

我正在使用这个类为纹理分配内存并渲染它

#import <Foundation/Foundation.h>
#import <GLKit/GLKit.h>

@interface PSSprite : NSObject

@property (assign) GLKVector2 position;
@property (assign) CGSize contentSize;
@property (assign) GLKVector2 moveVelocity;

- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect;
- (void)render;
- (void)update:(float)dt;

@end

#import "PSSprite.h"

typedef struct {
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

typedef struct {
    TexturedVertex bl;
    TexturedVertex br;    
    TexturedVertex tl;
    TexturedVertex tr;    
} TexturedQuad;

@interface PSSprite()

@property (strong) GLKBaseEffect * effect;
@property (assign) TexturedQuad quad;
@property (strong) GLKTextureInfo * textureInfo;

@end

@implementation PSSprite
@synthesize effect = _effect;
@synthesize quad = _quad;
@synthesize textureInfo = _textureInfo;
@synthesize position = _position;
@synthesize contentSize = _contentSize;
@synthesize moveVelocity = _moveVelocity;

- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect {
    if ((self = [super init])) {  
        // 1
        self.effect = effect;

        // 2
        NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithBool:YES],
                              GLKTextureLoaderOriginBottomLeft, 
                              nil];

        // 3
        NSError * error;
        NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
        // 4
        self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
        if (self.textureInfo == nil) {
            NSLog(@"Error loading file: %@", [error localizedDescription]);
            return nil;
        }
        self.contentSize = CGSizeMake(self.textureInfo.width, self.textureInfo.height);
        //Set up Textured Quad
        TexturedQuad newQuad;
        newQuad.bl.geometryVertex = CGPointMake(0, 0);
        newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0);
        newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
        newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height);

        newQuad.bl.textureVertex = CGPointMake(0, 0);
        newQuad.br.textureVertex = CGPointMake(1, 0);
        newQuad.tl.textureVertex = CGPointMake(0, 1);
        newQuad.tr.textureVertex = CGPointMake(1, 1);
        self.quad = newQuad;

    }
    return self;
}



- (GLKMatrix4) modelMatrix {

    GLKMatrix4 modelMatrix = GLKMatrix4Identity;    
    modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, 0);
    modelMatrix = GLKMatrix4Translate(modelMatrix, -self.contentSize.width/2, -self.contentSize.height/2, 0);
    return modelMatrix;

}

- (void)render { 

    // 1
    self.effect.texture2d0.name = self.textureInfo.name;
    self.effect.texture2d0.enabled = YES;

    self.effect.transform.modelviewMatrix = self.modelMatrix;

    // 2    
    [self.effect prepareToDraw];

    // 3
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    // 4
    long offset = (long)&_quad;        
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

- (void)update:(float)dt {
    GLKVector2 curMove = GLKVector2MultiplyScalar(self.moveVelocity, dt);
    self.position = GLKVector2Add(self.position, curMove);    
}

@end

我不允许 Dealloc 或释放任何东西,因为我的程序使用 ARC 来自动处理内存。

调试和分析后,它显示我有数千个引用计数为 +1 的 malloc,来自:libGFXShared.dylib。负责的调用者是 gfxAllocateTextureLevel

【问题讨论】:

    标签: ios objective-c opengl-es memory-leaks


    【解决方案1】:

    在这里找到答案:Release textures (GLKTextureInfo objects) allocated by GLKTextureLoader

    显然,将纹理传递给 OpenGL 会让 OpenGL 负责内存,从而迫使您使用 glDeleteTextures 将其删除。

    【讨论】:

      猜你喜欢
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多