内存泄漏与CIColor spritekit

时间:2015-05-12 17:20:36

标签: memory-leaks sprite-kit instruments

我创建了一个可生成hud项的类,此hud项可以为生成的纹理设置动画,该纹理是使用cicolor创建的渐变,然后将其保存到uiimage中,而uiimage又用于sktexture。我现在已经注意到我在我的应用程序中获得了大量的内存增长,并通过乐器运行它已经向我展示了这一点,但我不能为生活弄清楚最新情况:

这是我得到的错误enter image description here 你无法真正看到这个问题所以它给了我91.4%的代码:

animatedGraphic = [[SKSpriteNode alloc]initWithTexture:[[TextureList sharedManager]returnGradientofSize:[[TextureList sharedManager]returnTextureSize:kGMHUDFlowerTarget] topColor:[CIColor colorWithRed:255.0/255.0 green:171.0/255.0 blue:121.0/255.0] bottomColor:[CIColor colorWithRed:225.0/255.0 green:57.0/255.0 blue:86.0/255.0]] color:[UIColor orangeColor] size:CGSizeMake(0, self.frame.size.height)];
            animatedGraphic.anchorPoint = CGPointMake(0, 0.5);
            animatedGraphic.zPosition = self.zPosition+1;
            [self addChild:animatedGraphic];

使用渐变来表示sktexture的代码:

-(SKTexture*)returnHorizontalGradientofSize:(CGSize)size
                                  leftColor:(CIColor*)leftColor
                                 rightColor:(CIColor*)rightColor{

    CIContext *coreImageContext = [CIContext contextWithOptions:nil];
    CIFilter *gradientFilter = [CIFilter filterWithName:@"CILinearGradient"];
    [gradientFilter setDefaults];
    CIVector *startVector = [CIVector vectorWithX:0 Y:size.height/2];
    CIVector *endVector = [CIVector vectorWithX:size.width Y:size.height/2];
    [gradientFilter setValue:startVector forKey:@"inputPoint0"];
    [gradientFilter setValue:endVector forKey:@"inputPoint1"];
    [gradientFilter setValue:leftColor forKey:@"inputColor0"];
    [gradientFilter setValue:rightColor forKey:@"inputColor1"];
    CGImageRef cgimg = [coreImageContext createCGImage:[gradientFilter outputImage]
                                              fromRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *theImage = [UIImage imageWithCGImage:cgimg];
    CFRelease(cgimg);
    return [SKTexture textureWithImage:theImage];
}

下面是hud项目的代码:

#import "ItemHud.h"
#import "TextureList.h"
#import "UnlockController.h"

@interface ItemHud ()

@property (nonatomic) double scoreIncrement;
@property (nonatomic) double increment;
@property (nonatomic) double barIncrement;
@property (nonatomic) double updateIncrement;
@property (nonatomic) BOOL barAnimating;
@end

@implementation ItemHud

@synthesize theLabel;
@synthesize theLabelTwo;
@synthesize animatedGraphic;
@synthesize iconGraphic;


-(id)initWithImageNamed:(NSString *)ImageName
              withLabel:(NSString *)LabelName
           withLabelTwo:(NSString *)LabelNameTwo
        withIconGraphic:(NSString *)iconGraphicName
    withAnimatedGraphic:(BOOL)AnimatedGraphicName{

    if (self = [super init]) {

        if (ImageName)
        {
            self.size = [[TextureList sharedManager]returnTextureSize:ImageName];
            self.texture = nil;
            self.color = [UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.65];
            self.userInteractionEnabled = NO;
            _barAnimating = NO;

        }
        if (AnimatedGraphicName) {
            animatedGraphic = [[SKSpriteNode alloc]initWithTexture:[[TextureList sharedManager]returnGradientofSize:[[TextureList sharedManager]returnTextureSize:kGMHUDFlowerTarget] topColor:[CIColor colorWithRed:255.0/255.0 green:171.0/255.0 blue:121.0/255.0] bottomColor:[CIColor colorWithRed:225.0/255.0 green:57.0/255.0 blue:86.0/255.0]] color:[UIColor orangeColor] size:CGSizeMake(0, self.frame.size.height)];
            animatedGraphic.anchorPoint = CGPointMake(0, 0.5);
            animatedGraphic.zPosition = self.zPosition+1;
            [self addChild:animatedGraphic];

        }
        if (iconGraphicName) {
            if ([iconGraphicName isEqualToString:kGMHUDLevelIcon1] || [iconGraphicName isEqualToString:kGMHUDLevelIcon2] || [iconGraphicName isEqualToString:kGMHUDLevelIcon3] || [iconGraphicName isEqualToString:kGMHUDLevelIcon4]|| [iconGraphicName isEqualToString:kGMHUDLevelIcon5] || [iconGraphicName isEqualToString:kGMHUDLevelIcon6] || [iconGraphicName isEqualToString:kGMHUDLevelIcon7] || [iconGraphicName isEqualToString:kGMHUDLevelIcon8] || [iconGraphicName isEqualToString:kGMHUDLevelIcon9]) {
                iconGraphic = [[SKSpriteNode alloc]initWithTexture:[SKTexture textureWithImageNamed:iconGraphicName] color:nil size:[[TextureList sharedManager]returnTextureSize:kGMHUDLevelIcon1]];
            }
            else{
               iconGraphic = [[SKSpriteNode alloc]initWithTexture:[SKTexture textureWithImageNamed:iconGraphicName] color:nil size:[[TextureList sharedManager]returnTextureSize:iconGraphicName]];
            }
            iconGraphic.zPosition = self.zPosition+1;
            [self addChild:iconGraphic];
            [self setGraphicRight:NO];
        }
        if (LabelName) {
            theLabel = [SKLabelNode labelNodeWithFontNamed:kFontName];
            [theLabel setFontColor:[UIColor whiteColor]];
            [theLabel setFontName:kFontName];
            [theLabel setFontSize:kFontSizeMDMedium];
            [theLabel setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeLeft];
            [theLabel setVerticalAlignmentMode:SKLabelVerticalAlignmentModeCenter];
            theLabel.text = LabelName;
            [self addChild:theLabel];
            [self setHudDefaults:YES];
        }
        if (LabelNameTwo) {
            theLabelTwo = [SKLabelNode labelNodeWithFontNamed:kFontName];
            [theLabelTwo setFontColor:[UIColor whiteColor]];
            [theLabelTwo setFontName:kFontName];
            [theLabelTwo setFontSize:kFontSizeMDMedium];
            [theLabelTwo setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeRight];
            [theLabelTwo setVerticalAlignmentMode:SKLabelVerticalAlignmentModeCenter];
            theLabelTwo.text = LabelNameTwo;
            [self addChild:theLabelTwo];
            [self setHudDefaults:NO];
        }

    }
    return self;
}

-(void)setBackgroundImage:(SKTexture*)theTexture{

    self.texture = theTexture;
}

-(void)setHudDefaults:(BOOL)singleLabel{

    theLabelTwo.position = CGPointMake(self.position.x+self.frame.size.width/2,self.position.y);
    animatedGraphic.position = CGPointMake(-self.frame.size.width/2,self.position.y);

    if (singleLabel) {
        [theLabel setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeCenter];
        theLabel.position = CGPointMake(self.position.x,self.position.y);
    }
    else{
        theLabel.position = CGPointMake(theLabelTwo.position.x-theLabelTwo.frame.size.width/2-20,self.position.y);
        [theLabel setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeRight];
    }

    theLabel.zPosition = self.zPosition+1;
    theLabelTwo.zPosition = self.zPosition+1;

}

-(void)setGraphicRight:(BOOL)placeRight{

    if (placeRight) {
        iconGraphic.position = CGPointMake(self.frame.size.width/2,-self.frame.size.height/4);
        iconGraphic.zPosition = animatedGraphic.zPosition+1;
    }
    else{
        iconGraphic.position = CGPointMake(-self.frame.size.width/2,-self.frame.size.height/4);
        iconGraphic.zPosition = animatedGraphic.zPosition+1;
    }
}

-(void)setBarProgress:(int)flowerTarget currentFlowers:(int)currentFlowers{

    double increment = (double)flowerTarget/100;
    //NSLog(@"increment is %f",increment);
    double barIncrement = (double)self.frame.size.width/100;
    //NSLog(@"BAR increment is %f",barIncrement);
    double barState = (barIncrement/increment)*currentFlowers;
    //NSLog(@"BAR state is %f",barState);

    /*if (animatedGraphic.frame.size.width >= self.frame.size.width && !_barAnimating) {
        _barAnimating = YES;
        [self animateBar:YES];
    }
    else if (animatedGraphic.frame.size.width < self.frame.size.width && _barAnimating){
        _barAnimating = NO;
        [self animateBar:NO];
    }*/

    animatedGraphic.size = CGSizeMake(barState, self.frame.size.height);

}

-(void)setBarValues:(int)startValue increment:(int)increment nextObject:(int)nextObject{

    //NSLog(@"0:Totalscore is %i",[[UserDetails sharedManager]userTotalScore]);
    //NSLog(@"1:StartValue %i",startValue);
    //NSLog(@"2:Increment %i",increment);
    //NSLog(@"3:Nextobject %i",nextObject);

    _scoreIncrement = (double)startValue/(double)nextObject;
    //NSLog(@"increment is %f",increment);

    _barIncrement = (double)self.frame.size.width/100;
    //NSLog(@"bar increment is %f",barIncrement);

    _updateIncrement = ((double)startValue/_scoreIncrement)/100;
    //NSLog(@"update increment is %f",updateIncrement);

    //NSLog(@"4:Animate %f",_barIncrement/_updateIncrement*increment);
    animatedGraphic.size = CGSizeMake(_barIncrement/_updateIncrement*increment, self.frame.size.height);

}
-(void)updateBarProgress:(int)update{

    animatedGraphic.size = CGSizeMake(_barIncrement/_updateIncrement*update, self.frame.size.height);
    //hudFx.position = CGPointMake(animatedGraphic.frame.size.width-2, animatedGraphic.position.y);

}

-(void)setBarValues:(int)startValue nextObject:(int)nextObject animated:(BOOL)animated{

    // start value is difference between unlock score and current value
    // next object is score to unlock item

    // all unlocks done
    if ([[UnlockController sharedManager]allunlocksOpen]) {
        theLabel.text = @"ALL ITEMS UNLOCKED";
        return;
    }

    __block int count = 0;

    double increment = (double)startValue/(double)nextObject;
    //NSLog(@"increment is %f",increment);

    double countUp = nextObject-startValue;
    //NSLog(@"countup is %f",countUp);

    double barIncrement = (double)self.frame.size.width/100;
    //NSLog(@"bar increment is %f",barIncrement);

    double updateIncrement = ((double)startValue/increment)/100;
    //NSLog(@"update increment is %f",updateIncrement);

    if (!animated) {
        animatedGraphic.size = CGSizeMake(barIncrement/updateIncrement*startValue, self.frame.size.height);
        //hudFx.position = CGPointMake(animatedGraphic.frame.size.width-2, animatedGraphic.position.y);
    }
    else{

        SKAction *delay = [SKAction waitForDuration:0.0];
        SKAction *animateCount = [SKAction runBlock:^{
            count++;
            animatedGraphic.size = CGSizeMake(barIncrement*count, self.frame.size.height);
            //hudFx.position = CGPointMake(animatedGraphic.frame.size.width-2, animatedGraphic.position.y);

        }];
        SKAction *animateSequence = [SKAction sequence:@[animateCount,delay]];
        SKAction *repeatSequence = [SKAction repeatAction:animateSequence count:(double)countUp/updateIncrement];

        [animatedGraphic runAction:repeatSequence completion:^{

        }];
    }
}

-(void)animateBar:(BOOL)animate{

    SKAction *delay = [SKAction waitForDuration:0.15];

    SKAction *changeToAnimateBar = [SKAction runBlock:^{

        animatedGraphic.texture = [[TextureList sharedManager]returnGradientofSize:[[TextureList sharedManager]returnTextureSize:kGMHUDFlowerTarget] topColor:[CIColor colorWithRed:255.0/255.0 green:244.0/255.0 blue:155.0/255.0] bottomColor:[CIColor colorWithRed:225.0/255.0 green:57.0/255.0 blue:86.0/255.0]];
    }];
    SKAction *changeToDefaultBar = [SKAction runBlock:^{

        animatedGraphic.texture = [[TextureList sharedManager]returnGradientofSize:[[TextureList sharedManager]returnTextureSize:kGMHUDFlowerTarget] topColor:[CIColor colorWithRed:255.0/255.0 green:171.0/255.0 blue:121.0/255.0] bottomColor:[CIColor colorWithRed:225.0/255.0 green:57.0/255.0 blue:86.0/255.0]];
    }];

    SKAction *animateSequence = [SKAction sequence:@[changeToAnimateBar,delay,changeToDefaultBar,delay]];
    SKAction *animatingBarLoop = [SKAction repeatActionForever:animateSequence];

    if (animate) {
        [self runAction:animatingBarLoop withKey:@"animatingBar"];
    }
    else{
        [self removeActionForKey:@"animatingBar"];
        [self runAction:changeToDefaultBar withKey:@"defaultBar"];
    }
}

1 个答案:

答案 0 :(得分:0)

这对于AGSpriteButton类来说是一个问题,它占用了内存,因此在加载广告时最终导致崩溃,你可以在这里找到修复:

SKScene Fails to deallocate memory resulting in bounded memory growth