簡體   English   中英

@autoreleasepool塊中的內存泄漏

[英]memory leak in @autoreleasepool block

我使用Xcode 4.4,並使用ARC開發適用於iOS 5.1的應用程序。 我有一個線程(主線程除外)可以定期調用下面的方法。

- (void)updateLabels:(NSTimeInterval)timeSinceLastUpdate
{
        int lastTime = self.time;
        self.scoreScale -= ((self.scoreScale-1)/5);
        self.time -= timeSinceLastUpdate;
        if (self.time <= 0) {
            self.time = 0.0;
        }
        if (lastTime != (int) self.time) {
            self.timeChanged = YES;
        }
    @autoreleasepool {
        NSString *timeString = [NSString stringWithFormat:@"%.2d:%.2d",(int)(self.time/60),((int)self.time%60)]; //leak!!!
        if (self.scoreScale <=1) self.scoreScale = 1;

        GLKBaseEffect *scoreValueEffect = [self.sprites objectForKey:@"score_value"];
        if (self.scoreChanged) {
            scoreValueEffect = [[ILUtils sharedInstance] makeEffectWithString:[NSString stringWithFormat:@"%@",self.score] alignment:UITextAlignmentLeft fontName:@"WetLetters EFN" fontSize:20 withViewSize:self.view.bounds.size withRect:CGRectMake(935, 50, 100, 30)];
        }
        scoreValueEffect.transform.modelviewMatrix = [[ILUtils sharedInstance] setupSpriteModelviewMatrixWithViewRect:CGRectMake(955, 46-(30*self.scoreScale-30)/2, 100*self.scoreScale, 30*self.scoreScale)];
        [self.sprites setObject:scoreValueEffect forKey:@"score_value"];

        if (self.timeChanged) {
            GLKBaseEffect *timeValueEffect = [[ILUtils sharedInstance] makeEffectWithString:timeString alignment:UITextAlignmentLeft fontName:@"WetLetters EFN" fontSize:24 withViewSize:self.view.bounds.size withRect:CGRectMake(955, 75, 100, 30)];
            [self.sprites setObject:timeValueEffect forKey:@"time_value"];
        }
    }
}

使用儀器時,我可以看到內存使用量隨時間增加。 當我注釋掉創建字符串的行時,內存使用情況穩定。 我也嘗試使用alloc和init方法創建字符串,但沒有幫助。 我在https://stackoverflow.com/questions/ask?title=@autoreleasepool%20not%20working中發現了類似的線程,但是啟用/禁用NSZombieEnabled選項沒有任何區別。

我無法弄清為什么我按照https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html中的說明使用@autorelease塊,為什么所有這些字符串都沒有被釋放。

我錯過了什么? 謝謝。

// makeEffectWithString調用的makeEffectWithString

- (GLKBaseEffect*)makeEffectWithString:(NSString*)string alignment:(UITextAlignment)alignment fontName:(NSString*)name fontSize:(CGFloat)size withViewSize:(CGSize)viewSize withRect:(CGRect)rect
{
    GLKBaseEffect *effect = [[GLKBaseEffect alloc] init];
    effect.texture2d0.enabled = YES;
    effect.texture2d0.name = [self textureWithString:string dimensions:rect.size alignment:alignment fontName:name fontSize:size].name;
    effect.transform.projectionMatrix = [self setupOrthoProjectionMatrixWithViewSize:viewSize];
    effect.transform.modelviewMatrix = [[ILUtils sharedInstance] setupSpriteModelviewMatrixWithViewRect:rect];
    effect.useConstantColor = YES;
    effect.constantColor = GLKVector4Make(0.7f,0.7f,0.7f,0.7f);

    return effect;
}

- (GLKTextureInfo*)textureWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(UITextAlignment)alignment fontName:(NSString*)name fontSize:(CGFloat)size
{
    UIFont *font = [UIFont fontWithName:name size:size];

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef context = CGBitmapContextCreate(nil, dimensions.width, dimensions.height, 8, dimensions.width, colorSpace, kCGImageAlphaOnly);
    CGColorSpaceRelease(colorSpace);
    CGContextSetGrayFillColor(context, 1.0, 1.0);

    UIGraphicsPushContext(context);
    [string drawInRect:CGRectMake(0, 0, dimensions.width, dimensions.height) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:alignment];
    UIGraphicsPopContext();

    NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderOriginBottomLeft];
    GLKTextureInfo *texture = [GLKTextureLoader textureWithCGImage:CGBitmapContextCreateImage(context) options:options error:nil];

    CGContextRelease(context);

    return texture;

}

//編輯

- (void)drawSpriteUsingEffect:(GLKBaseEffect*)effect
{

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(12));

    [effect prepareToDraw];
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

您可以使用分配工具來“標記堆”。 似乎有一些有關如何調試此類內存問題的說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM