I’m developing an app for iOS. This is a game.
In the game screen user can load object subclassed from UIImageView. To save the game I’ve developed this function that iterates by the subviews array of the main view and generates an XML string.
#pragma mark I/O Functions
-(NSString *)getXMLFromItemsView:(UIView *)items
{
int a;
NSString *XML = [[[NSString alloc] init] autorelease];
XML = [XML stringByAppendingString:@"<PAGE>"];
for (a=0;a<[items.subviews count];a++)
{
iItem *item = [items.subviews objectAtIndex:a];
if ([item isKindOfClass:[iItem class]] || [item isKindOfClass:[iText class]])
{
NSLog(@"INFO -> Saving...Item Id: %d",item.itemId);
XML = [XML stringByAppendingString:@"<ITEM>\n"];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<CLASS>%@</CLASS>\n",[item class]]];
//OriginalTransform
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.a>%f</originalTransform.a>\n",item.originalTransform.a]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.b>%f</originalTransform.b>\n",item.originalTransform.b]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.c>%f</originalTransform.c>\n",item.originalTransform.c]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.d>%f</originalTransform.d>\n",item.originalTransform.d]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.tx>%f</originalTransform.tx>\n",item.originalTransform.tx]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalTransform.ty>%f</originalTransform.ty>\n",item.originalTransform.ty]];
//InitialTransform
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.a>%f</initialTransform.a>\n",item.initialTransform.a]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.b>%f</initialTransform.b>\n",item.initialTransform.b]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.c>%f</initialTransform.c>\n",item.initialTransform.c]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.d>%f</initialTransform.d>\n",item.initialTransform.d]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.tx>%f</initialTransform.tx>\n",item.initialTransform.tx]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<initialTransform.ty>%f</initialTransform.ty>\n",item.initialTransform.ty]];
//OriginalFrame
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalFrame.x>%f</originalFrame.x>\n",item.originalFrame.origin.x]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalFrame.y>%f</originalFrame.y>\n",item.originalFrame.origin.y]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalFrame.w>%f</originalFrame.w>\n",item.originalFrame.size.width]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<originalFrame.h>%f</originalFrame.h>\n",item.originalFrame.size.height]];
//zOrder
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<zOrder>%d</zOrder>\n",item.zOrder]];
//itemId
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<itemId>%d</itemId>\n",item.itemId]];
//itemIdColor
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<itemIdColor>%d</itemIdColor>\n",item.itemIdColor]];
//itemIdTexture
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<itemIdTexture>%d</itemIdTexture>\n",item.itemIdTexture]];
//itemIdStyle
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<itemIdStyle>%d</itemIdStyle>\n",item.itemIdStyle]];
//textureLevel
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<textureLevel>%d</textureLevel>\n",item.textureLevel]];
//currentSizePercent
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentSizePercent>%f</currentSizePercent>\n",item.currentSizePercent]];
//currentRotation
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentRotation>%f</currentRotation>\n",[item currentRotation]]];
//holdItem
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<holdItem>%d</holdItem>\n",item.holdItem]];
//isInverted
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<isInverted>%d</isInverted>\n",item.isInverted]];
//isMerged
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<isMerged>%d</isMerged>\n",item.isMerged]];
//selectedFrame
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<selectedFrame>%@</selectedFrame>\n",item.selectedFrame]];
//mergedFrame
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<mergedFrame>%@</mergedFrame>\n",item.mergedFrame]];
//NSLog(@"Item Saved Frame: X:%f Y:%f W:%f H:%f",item.frame.origin.x,item.frame.origin.y,item.frame.size.width,item.frame.size.height);
//currentFrame
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentFrame.x>%f</currentFrame.x>\n",item.frame.origin.x]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentFrame.y>%f</currentFrame.y>\n",item.frame.origin.y]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentFrame.w>%f</currentFrame.w>\n",item.frame.size.width]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentFrame.h>%f</currentFrame.h>\n",item.frame.size.height]];
//currentBounds
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentBounds.x>%f</currentBounds.x>\n",item.bounds.origin.x]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentBounds.y>%f</currentBounds.y>\n",item.bounds.origin.y]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentBounds.w>%f</currentBounds.w>\n",item.bounds.size.width]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentBounds.h>%f</currentBounds.h>\n",item.bounds.size.height]];
//currentTransform
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.a>%f</currentTransform.a>\n",item.transform.a]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.b>%f</currentTransform.b>\n",item.transform.b]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.c>%f</currentTransform.c>\n",item.transform.c]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.d>%f</currentTransform.d>\n",item.transform.d]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.tx>%f</currentTransform.tx>\n",item.transform.tx]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentTransform.ty>%f</currentTransform.ty>\n",item.transform.ty]];
if ([[NSString stringWithFormat:@"%@",[item class]] isEqual:@"iText"])
{
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<currentText>%@</currentText>\n",[item text]]];
}
XML = [XML stringByAppendingString:@"</ITEM>\n"];
}
}
if (fondo)
{
XML = [XML stringByAppendingString:@"<FONDO>\n"];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<selectedFrame>%@</selectedFrame>",fondo.selectedFrame]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<picturePath>%@</picturePath>",fondo.picturePath]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<idCurrentColor>%d</idCurrentColor>",fondo.idCurrentColor]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<idCurrentTexture>%d</idCurrentTexture>",fondo.idCurrentTexture]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<idCurrentStyle>%d</idCurrentStyle>",fondo.idCurrentStyle]];
XML = [XML stringByAppendingString:[NSString stringWithFormat:@"\t<textureLevel>%d</textureLevel>",fondo.textureLevel]];
XML = [XML stringByAppendingString:@"</FONDO>\n"];
}
XML = [XML stringByAppendingString:@"</PAGE>"];
NSLog(@"INFO -> ItemsViewXML: %@",XML);
return XML;
}
At the moment this method works fine if the amount of items to iterate is low >20. But when it has to handle more than 50 items the app crashes because memory.
I’ve debugged this method using instruments and no leaks where detected, but the allocations increase until use a high amount of RAM.
It’s not normal that creating a string uses more than 100MB of VM.
Anyone knows which I’m loosing?
Thanks.
You should use
NSMutableStringwhen building a string from parts.But in this case you might even want to use a proper XML serializer like
NSXMLDocumentetc.