2012-05-07 2 views
0

Я использую RaptureXML для анализа XML-файла, который описывает разные фильтры (с довольно сложной структурой), которые я затем создаю как объекты Obj-C. Все работает отлично!Утечки при использовании RaptureXML с XPath

Однако инструменты обнаруживают несколько утечек в libxml2.2.dylib (см. Снимок экрана), и я не могу найти что-либо в Интернете, которое могло бы помочь мне в этой проблеме.

Вот ссылка на скриншот Утечки инструмент (я не могу отправить его в софа еще ...)

http://imageshack.us/photo/my-images/850/bildschirmfoto20120507ud.png/

Вот код, я использую для анализа файла XML :

RXMLElement *rootXML = [RXMLElement elementFromXMLData:xmlDataFile]; 

FilterLogic_Management *filterManager = [[FilterLogic_Management alloc] init]; 

NSString *queryPath = [NSString stringWithFormat:@"//%@[@id=%i]/filterSettings/fqFilter", FilterTypeAsString, FilterNum]; 

//WHAT AM I DOING? Consider two filter types: Distance and Price. Each filter type consists of different thresholds (e.g., <8 $; 8 - 15 $; > 15 $). All of these values are in an XML file which I need to parse and translate into my "real" filters that I use in the App. 

//Step 1: Iterate over all FilterTypes to find the entry in the XML file that describes the currently selected FilterType and its FilterNum 

[rootXML queryPath usingBlock:^(RXMLElement *filterElement) { 

    NSMutableArray *currentThresholds = [[NSMutableArray alloc] init]; 

    float currentWeight = [filterElement attribute:@"weightFactor"].floatValue; //e.g., 1.0   
    NSString *currentMarkerUnit = [filterElement attribute:@"markerUnit"]; //e.g., $ or € 
    NSString *currentFilterType = [filterElement attribute:@"groupType"]; //e.g., "Distance" or "Price" 



    //Step 2: Iterate over all Filters for current FilterType <- a FilterType consists of an array of Filters... 


    [filterElement iterate:@"filter" usingBlock: ^(RXMLElement *filter) { 
     NSString *filterType = [filter attribute:@"filterType"]; 

     if(filterType != LogicalConjunction){ 
      //Step 3-a: Create threshold with more than one threshold 

      float threshold = [filter attribute:@"threshold"].floatValue; 

      FilterLogic_FilterThreshold *newThreshold = [FilterLogic_FilterThreshold FilterThresholdMakeWithOneThreshold:threshold FilterWrapperType:filterTypeAsEnum MarkerUnit:currentMarkerUnit IsInitiallyActive:isInitiallyActive]; 

      [currentThresholds addObject:newThreshold]; 
     }else{ 
      //Step 3-b: Create threshold with multiple thresholds 
      NSLog(@"Creating filter with multiple thresholds"); 

      FilterLogic_FilterThreshold *logicalThreshold = [FilterLogic_FilterThreshold FilterThresholdMakeLogicalThreshold:filterTypeAsEnum MarkerUnit:currentMarkerUnit IsInitiallyActive:isInitiallyActive]; 

      NSMutableArray *subFilterThresholds = [[NSMutableArray alloc] init]; 
      [filter iterate:@"filter" usingBlock: ^(RXMLElement *subFilter) { 
       //Step-3b-x Iterate over sub-thresholds 
       float threshold = [subFilter attribute:@"threshold"].floatValue; 

       FilterLogic_FilterThreshold *subFilterThreshold = [FilterLogic_FilterThreshold FilterThresholdMakeWithOneThreshold:threshold]; 


       [subFilterThresholds addObject:subFilterThreshold]; 

      }]; 
      if([subFilterThresholds count]>1) 
      { 
       FilterLogic_FilterThreshold *newThreshold = [FilterLogic_FilterThreshold FilterThresholdMakeFromLowerFilterThreshold:[subFilterThresholds objectAtIndex:0] UpperFilterThreshold:[subFilterThresholds objectAtIndex:1] LogicalFilterThreshold:logicalThreshold]; 

       [currentThresholds addObject:newThreshold]; 
      } 

     } 
    }];  

    FilterLogic_Filter *newFilter = [[FilterLogic_Filter alloc] initFilterWithType:FilterTypeAsEnum ArrayOfFilterLogic_FilterThresholds:currentThresholds Weight:currentWeight InitiallyActive:YES]; 



    [filterManager registerFilterWrapper:newFilter]; 

}]; 

//thought that these commands might help... it seems they don't. Probably misusing them! 
xmlCleanupMemory(); 
xmlCleanupParser(); 

//if([filterManager countOfFilters]>0){ 
    NSLog(@"Filter parsing done!"); 
    return filterManager; 

Большое спасибо за любую помощь/совет !!

ответ

0

Попробуйте поместить весь queryPath с помощью бита Block в @autoreleasepool {...}. Просто идея.

+0

Благодарю вас за вашу идею, rnystrom. Тем не менее, утечки все еще происходят:/ – Wirsing

+0

Попробуйте запустить установку Leaks Instrument «Просочившиеся блоки для вызова дерева» и выберите «Инвертировать дерево вызовов» и «Скройте системные библиотеки» и снова проверьте утечки. Это может помочь определить, где происходит утечка. – rnystrom

+0

Отлично! Thx, Invert Call Tree действительно помогает! Она протекает в двух точках: - [RXMLElement childrenWithRootXPath:] -> 21 KB с 111 протечек - [RXMLElement атрибут:] -> 4 KB 265 протечек Таким образом, первый не протекает часто, но когда это делает, его «тяжелый» – Wirsing