Note that there are some explanatory texts on larger screens.

plurals
  1. POStrange issue with IOS6 and UIImage
    primarykey
    data
    text
    <p>Currently, one of my game is using UIKit which its image comes from the spritesheets. Prior IOS6, the total memory used caps at 80mb at the title screen, but at IOS6, it spikes to 300MB. Even when I removed UIKit, the memory used is still like 80mb - 90mb from Cocos2d. Anyone has any idea why this is happening?</p> <p>below are the codes which I cache the texture and use them:</p> <pre><code>//this function will be called at the beginning of the app to cache the image, so far it does not cause any memory spike. +(void) cacheCommonlyUsedTexture { cachedSpriteFrames = [[NSMutableDictionary alloc] initWithCapacity:0]; cachedSprite = [[NSMutableDictionary alloc] initWithCapacity:0]; NSString* levelPath = [ [NSBundle mainBundle] pathForResource:texName ofType:@"plist"]; NSString* imagePath = [ [NSBundle mainBundle] pathForResource:texName ofType:@"png"]; cachedFrameDict = [[NSDictionary dictionaryWithContentsOfFile:levelPath] retain]; NSData* tempData = [[NSData alloc] initWithContentsOfFile:imagePath]; UIImage* mainImg = [[UIImage alloc] initWithData:tempData]; NSDictionary* dict = [cachedFrameDict objectForKey:@"frames"]; for (id key in [dict allKeys]) { NSDictionary* spriteDict = [dict objectForKey:key]; if (spriteDict) { CGRect frameOfSprite = CGRectFromString( [spriteDict objectForKey:@"frame"]); CGImageRef imageRef = CGImageCreateWithImageInRect([mainImg CGImage], frameOfSprite); UIImage* image = [[UIImage alloc] initWithCGImage:imageRef]; CGImageRelease(imageRef); if (image) { [cachedSpriteFrames setObject:image forKey:key]; [image release]; } } } [mainImg release]; } //this selector actually gets the spriteframe +(UIImage*) imageFromPlist:(NSString*) plist withFrameName:(NSString*) frameName { NSDictionary* fileDict; UIImage* mainImg; NSData* mainData; if ([plist isEqualToString:texName] &amp;&amp; [cachedSpriteFrames objectForKey:frameName]) { id returnImage = [[cachedSpriteFrames objectForKey:frameName] retain]; return returnImage; } else { NSString* imagePath = [ [NSBundle mainBundle] pathForResource:plist ofType:@"png"]; NSString* levelPath = [ [NSBundle mainBundle] pathForResource:plist ofType:@"plist"]; fileDict = [NSDictionary dictionaryWithContentsOfFile:levelPath]; mainData = [NSData dataWithContentsOfFile:imagePath]; } mainImg = [[UIImage alloc] initWithData:mainData]; if (fileDict) { NSDictionary* frameDict = [fileDict objectForKey:@"frames"]; if (frameDict) { NSDictionary* spriteDict = [frameDict objectForKey:frameName]; if (spriteDict) { CGRect frameOfSprite = CGRectFromString( [spriteDict objectForKey:@"frame"]); CGImageRef imageRef = CGImageCreateWithImageInRect([mainImg CGImage], frameOfSprite); UIImage* image = [[UIImage alloc] initWithCGImage:imageRef]; CGImageRelease(imageRef); [mainImg release]; return image; } } } [mainImg release]; return nil; } </code></pre> <p>my loading code:</p> <pre><code>@implementation CustomImageView (PlistLoading) //my UIKit elements are loaded from a plist. -(id) initWithDictionary:(NSDictionary *)dict withParentView:(id)pView { if ((self = [super initWithDictionary:dict withParentView:pView])) { self.userInteractionEnabled = NO; //the image views should not receive inputs UIImage* image = nil; self.backgroundColor = [UIColor clearColor]; if ([dict objectForKey:@"spritesheet"]) { image = [UIImage imageFromPlist:[dict objectForKey:@"spritesheet"] withFrameName:[dict objectForKey:@"spriteframe"]]; } else { if ([dict objectForKey:@"imageFile"]) { image = [UIImage spriteFromCache:[dict objectForKey:@"imageFile"]]; } } if (image) { if ([dict objectForKey:@"flip"]) { if ([[dict objectForKey:@"flip"] boolValue]) { CGImageRef imageRef = image.CGImage; UIImage* image2 = image; image = [[UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUpMirrored] retain]; [image2 release]; self.flipX = YES; } } self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, image.size.width, image.size.height); self.image = image; [image release]; //[image release]; } } return self; } @end </code></pre> <p>and lastly, what i used in my CustomImageView.h and .m. The reason why I used a CustomImageView instead of an UIImageView is that it seems to use lesser memories than UIImageView:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; @interface CustomImageView : UIView { CALayer* imageLayer; } @property (nonatomic, retain) UIImage* image; @property (nonatomic) BOOL drawBorder; @property (nonatomic) BOOL flipX; -(void) drawImage:(CGRect) rect; @end #import "CustomImageView.h" #import "UIView+PlistLoading.h" #import &lt;QuartzCore/QuartzCore.h&gt; @implementation CustomImageView @synthesize image, drawBorder, flipX; - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code drawBorder = NO; imageLayer = nil; self.backgroundColor = [UIColor clearColor]; } return self; } -(void) removeFromSuperview { self.image = nil; imageLayer.contents = nil; [imageLayer removeFromSuperlayer]; //[imageLayer release]; [super removeFromSuperview]; } -(void) dealloc { [super dealloc]; } -(void) setImage:(UIImage *)myImage { imageLayer = [CALayer layer]; imageLayer.frame = self.bounds; imageLayer.contents = (id) myImage.CGImage; imageLayer.masksToBounds = YES; if (flipX) { [imageLayer setAffineTransform:CGAffineTransformMakeScale(-1, 1)]; } [self.layer addSublayer:imageLayer]; //[imageLayer release]; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. */ -(void) drawImage:(CGRect) rect { if (self.image) { //[self.image drawInRect:rect]; if (drawBorder) { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, self.layer.borderColor); CGContextSetLineWidth(context, self.layer.borderWidth); UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:self.layer.cornerRadius]; [path addClip]; } else { } } } - (void)drawRect:(CGRect)rect { // Drawing code [self drawImage:rect]; } @end </code></pre> <p>Any advice is appreciated.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload