UIGraphicsBeginImageContext приводит к переполнению памяти (утечке) - PullRequest
3 голосов
/ 09 января 2012

В моем коде я растягиваю размер изображения до указанного размера.Код работает отлично до сих пор.У меня возникла проблема, что «UIGraphicsBeginImageContext ()» не освобождает память нового изображения.Итак, через 10 минут память переполняется, и приложение закрывается IOS.

У кого-нибудь есть решение этой проблемы?

- (CCSprite *)createStretchedSignFromString:(NSString *)string withMaxSize:(CGSize)maxSize withImage:(UIImage *)signImage
{
    // Create a new image that will be stretched with 10 px cap on each side
    UIImage *stretchableSignImage = [signImage stretchableImageWithLeftCapWidth:10 topCapHeight:10];

    // Set size for new image
    CGSize newImageSize = CGSizeMake(260.f, 78.0f);

    // Create new graphics context with size of the answer string and some cap
    UIGraphicsBeginImageContext(newImageSize);

    // Stretch image to the size of the answer string
    [stretchableSignImage drawInRect:CGRectMake(0.0f, 0.0f, newImageSize.width, newImageSize.height)];

    // Create new image from the context
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();

    // End graphics context
    UIGraphicsEndImageContext();

    // Create new texture from the stretched
    CCTexture2D *tex = [[CCTexture2D alloc] initWithImage:resizedImage];

    CCSprite *spriteWithTex = [CCSprite spriteWithTexture:tex];

    [[CCTextureCache sharedTextureCache] removeTexture:tex];

    [tex release];

    // Return new sprite for the sign with the texture  
    return spriteWithTex;
}

Вызывается этим кодом:

// Create image from image path
UIImage *targetSignImage = [UIImage imageWithContentsOfFile:targetSignFileName];

// Create new sprite for the sign with the texture
CCSprite *plainSign = [self createStretchedSignFromString:answerString withMaxSize:CGSizeMake(260.0f, 78.0f) withImage:targetSignImage];

Спасибо, пока.

1 Ответ

2 голосов
/ 13 января 2012

Я нашел решение своей проблемы.

Прежде всего, приведенный выше код является правильным и без утечек.

Проблема была вызвана удалением спрайта, которыйplanSign как ребенок.Спрайт удаляется таймером, который работает в другом потоке, поэтому в другом NSAutoreleasePool.

[timerClass removeTarget:targetWithSign] освободил пустой пул.

[timerClass performSelectorOnMainThread:@selector(removeTarget:) withObject:targetWithSign waitUntilDone:NO]; освободил правильный пул, который содержитцелевой спрайт и его дочерний элемент plainSign.

Спасибо SAKrisT и Стиги за ваши предложения.

...