Unable to Release Quartz 2D and Core Text created Images

366 views Asked by At

I am having a problem deleting my OpenGL ES textures are created via Quartz 2D and Core Text as shown below :

- (void)drawText:(CGContextRef)contextP startX:(float)x startY:(float)
y withText:(NSString *)standString
{
    CGContextTranslateCTM(contextP, 0, (bottom-top)*2);
    CGContextScaleCTM(contextP, 1.0, -1.0);

    CGRect frameText = CGRectMake(1, 0, (right-left)*2, (bottom-top)*2);

    NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:standString];
    [attrString addAttribute:NSFontAttributeName
                       value:[UIFont fontWithName:@"Helvetica-Bold" size:12.0]
                      range:NSMakeRange(0, attrString.length)];

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attrString));
    struct CGPath * p = CGPathCreateMutable();
    CGPathAddRect(p, NULL, frameText);
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,0), p, NULL);

    CTFrameDraw(frame, contextP);

    CFRelease(framesetter);
    CFRelease(frame);
    CGPathRelease(p);

    standString = nil;
    attrString = nil;

}

- (UIImage *)drawTexture : (NSArray *)verticesPassed : (UIColor *)statusColour : (NSString *)standString {

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();

    CGRect shp = [self boundFromFrame:verticesPassed];

    CGContextRef conPattern = CGBitmapContextCreate(NULL,
                                                    shp.size.width*sceneScalar,
                                                    shp.size.height*sceneScalar,
                                                    8,
                                                    0,
                                                    rgbColorSpace,
                                                    (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);

    CGColorSpaceRelease(rgbColorSpace);

    CGContextSetLineWidth(conPattern, 2);
    CGContextSetStrokeColorWithColor(conPattern, [UIColor blackColor].CGColor);

    Line * start = [sortedVertices objectAtIndex:0];
    StandPoint * startPoint = start.origin;

    CGContextMoveToPoint(conPattern, ([startPoint.x floatValue]-shp.origin.x)*sceneScalar , ([startPoint.y floatValue]-shp.origin.y)*sceneScalar);
    for (Line * vertice in sortedVertices) {
        StandPoint * standPoint = vertice.origin;
        CGContextAddLineToPoint(conPattern, ([standPoint.x floatValue]-shp.origin.x)*sceneScalar, ([standPoint.y floatValue]-shp.origin.y)*sceneScalar);
    }

    CGContextAddLineToPoint(conPattern, ([startPoint.x floatValue]-shp.origin.x)*sceneScalar , ([startPoint.y floatValue]-shp.origin.y)*sceneScalar);

    CGContextSetFillColorWithColor(conPattern, statusColour.CGColor);

    CGContextDrawPath(conPattern, kCGPathFillStroke);

    [self drawText:conPattern startX:0 startY:20 withText:standString];

    CGImageRef cgImage = CGBitmapContextCreateImage(conPattern);

    UIImage *imgPattern = [[UIImage alloc]initWithCGImage:cgImage];
    //UIImageWriteToSavedPhotosAlbum(imgPattern, nil, nil, nil); Uncomment if you need to view textures (photo album).

    self.standHeight = (top - bottom)*sceneScalar;
    self.standWidth = (right - left)*sceneScalar;
    self.xOffset = [startPoint.x floatValue]*sceneScalar;
    self.yOffset = (-[startPoint.y floatValue]*sceneScalar)+standHeight;

    CFRelease(cgImage);
    CGContextRelease(conPattern);

    return imgPattern;

}

However when I try to delete the textures as follows in viewWillDisappear, I can see (in instruments) that the memory is not released :

for (PolygonObject * stand in standArray) {
            GLuint name = stand.textureInfo.name;
            // delete texture from opengl
            glDeleteTextures(1, &name);
            // set texture info to nil
            stand.textureInfo = nil;
        }

I think that something is being retained in the texture somewhere in the code above. Can anyone suggest where ?

1

There are 1 answers

0
Jay Zhao On BEST ANSWER

As far as I can see, there's no memory leak in your code if you're using ARC. However, the UIImage returned from drawTexture may be retained by some other objects or by the auto release pool.

To check if this is the case, you may subclass UIImage, say UIDebugImage, override the dealloc method and set a breakpoint there to see if it's called.