2012-05-18 40 views
0

我正在开发iOS的应用程序。这是一场比赛。NSString从大量的项目

在游戏画面中,用户可以加载UIImageView中的子类。为了保存游戏,我开发了这个函数,该函数由主视图的子视图数组迭代并生成一个XML字符串。

#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; 
} 

此时此方法工作正常,如果要迭代的项目数量低于20。但是,当它必须处理超过50个项目时,应用程序因为内存而崩溃。

我已经使用仪器调试了此方法,没有发现泄漏,但分配增加,直到使用大量的RAM。

创建字符串使用超过100MB的VM是不正常的。

任何人都知道我失去了什么?

谢谢。

回答

1

从零件构建字符串时,应该使用NSMutableString

NSMutableString *xml = [NSMutableString string]; 
[xml appendFormat:@"....", ...]; 
[xml appendFormat:@"....", ...]; 

但在这种情况下,你甚至可能要使用适当的XML串行像NSXMLDocument

+0

霍莉的母亲扯淡!这就像一个魅力!非常感谢你!!!! – NemeSys

2

首先,你是不是创建一个字符串,你正在创建O(50),每串目的。这非常低效 - 在空间上(正如你在内存使用中看到的那样)和暂时的(它应该花费大量的时间)。

所以你可能去与Mattias˚建议,并使用一个可变的字符串,你会追加数据。

这会修复很多您所看到的内存压力问题,但仍然会很慢:
解析格式字符串相对耗时且保存操作应尽可能快。

所以我们就忽略症状,看问题:

你基本上要一个对象层次的档案,对不对?

在您的自定义类,实现-initWithCoder:-encodeWithCoder:

你保存然后操作变得简单

NSData *encodedObjectGraph = [NSKeyedArchiver archivedDataWithRootObject:yourObjectGraphsRootGoesHere]; 
NSError *saveError; 
if ([encodedObjectGraph writeToURL:storeURL options:NSDataWritingAtomic error:&saveError]) 
    return; 

NSLog(@"Uh oh: %@", saveError); 

和加载操作也仅是

NSError *loadError; 
NSData *savedObjectData = [NSData dataWithContentsOfURL:storeURL options:0 error:&loadError]; 
if (!savedObjectData) { 
    NSLog(@"No data at %@: %@", storeURL, loadError); 
    return; 
} 

objectGraphRoot = [NSKeyedUnarchiver unarchiveRootObjectWithData:savedObjectData]; 

(注:unarchiveRootObjectWithData:返回一个自动释放的对象!)

+0

这就像一个对象序列化,对不对?感谢您的详细解答。 – NemeSys

+0

是的,这是一个对象序列化。 – danyowdee