2016-07-15 58 views
2

我努力修复我所做的帮助函数中的内存泄漏。助手功能需要的从NSJSONSerialization处理基础对象时发生内存泄漏

+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError * _Nullable *)error 

的结果,所有的叶元素融入NSString的,如果他们是NSNumbers转换。

这里是方法:

-(NSArray *) stringisizeObjects:(NSArray *)inputArray{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSMutableArray *mutable = [[NSMutableArray alloc] initWithCapacity:[inputArray count]]; 

    for (int i = 0; i < [inputArray count]; i++) { 
     NSArray *keys = [inputArray[i] allKeys]; 

     NSMutableDictionary *addDictionary = [[NSMutableDictionary alloc] initWithCapacity:[keys count]]; 

     for (int j = 0; j < [keys count]; j++) { 

      id theObject = [[inputArray[i] objectForKey:keys[j]]autorelease]; 

      if ([theObject isKindOfClass:[NSNumber class]]) { 

       [addDictionary setObject:[theObject stringValue] forKey:keys[j]]; 
       [theObject release]; 

      }else if ([theObject isKindOfClass:[NSString class]]){ 
       [addDictionary setObject:[inputArray[i] objectForKey:keys[j]] forKey:keys[j]]; 
      } 

     } 
     [mutable addObject:addDictionary]; 
    } 
    NSArray *returnArray = [mutable copy]; 

    [mutable removeAllObjects]; 
    [mutable release]; 
    [pool drain]; 
    return returnArray; 
} 

这里是我得到的输入数组。

id parsedThingy = [NSJSONSerialization JSONObjectWithData:resultJSONData options:1 error:&jsonDecodeError]; 

之前,我可以将结果传递给我的stringisize方法,我必须确保我有NSDictionaries的一个NSArray与匹配的密钥。

NSArray *resultArray = [self stringisizeObjects:parsedThingy]; 

的X代码内存泄漏工具已经向我指出这种方法,我的问题的原因。

Instruments showing leaks

正如你可以看到我已经尝试了自动释放池,自动释放,释放包裹的东西。我只是在这里看不到任何方向。

这是一个24/7全天候运行的非ARC项目。

编辑:我接受了Droppy的建议,并尝试使用mutableCopy重写该方法。泄漏仍在那里。在这一点上,我唯一的工作可能是改变JSON的来源以仅发送字符串。 :(

-(NSArray *) stringisizeObjects2:(NSArray *)inputArray{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSMutableArray *mutableArray = [inputArray mutableCopy]; 

    for (int i = 0; i < [mutableArray count]; i++) { 
     NSMutableDictionary *mutableDict = [mutableArray[i] mutableCopy]; 
     NSArray *keys = [mutableDict allKeys]; 

     for (int j = 0; j < [keys count]; j++) { 
      if ([[mutableDict objectForKey:keys[j]] isKindOfClass:[NSNumber class]]) { 
       NSString *stringValue = [[mutableDict objectForKey:keys[j]] stringValue]; 

       [mutableDict removeObjectForKey:keys[j]]; 
       [mutableDict setObject:stringValue forKey:keys[j]]; 
      } 
     } 
     mutableArray[i] = [mutableDict copy]; 
     [mutableDict release]; 
    } 

    NSArray *returnArray = [mutableArray copy]; 

    [mutableArray release]; 
    [pool drain]; 
    return returnArray; 
} 
+0

貌似很多的代码,可以用'mutableCopy'所取代。 – Droppy

+0

我遇到了同样的数组内存泄漏问题。我在NSMutableArray中添加图像。即使我像你一样去除了所有物体,它仍然会泄漏。你无能为力,因为它依靠Xcode来清除内存。它在需要时做。但为了避免它的影响,您可以分开您的代码,并根据您的需要在主队列中运行一些部分,并在后台队列中运行一些部分。 – WasimSafdar

+0

在您的源代码中更改NSMutableArray * mutable = [[[[NSMutableArray alloc] initWithCapacity:[inputArray count]] autorelease];并添加[addDictionary release];紧随[mutable addObject:addDictionary];并返回可变; – larva

回答

1

问题:

  1. addDictionary称为alloc但不叫releaseautorelease
  2. returnArray = [可变副本]; //没有增加retainCount +1,需要autorelease这里
  3. id theObject = [inputArray[i] objectForKey:keys[j]]; //不需要自行释放或释放您不属于的对象
  4. add N SAutoreleasePool在此之上的底部只是什么也不做

解决方案:

-(NSArray *) stringisizeObjects:(NSArray *)inputArray{ 
    NSMutableArray *mutable = [[NSMutableArray alloc] initWithCapacity:[inputArray count]]; 

    for (int i = 0; i < [inputArray count]; i++) { 
     NSArray *keys = [inputArray[i] allKeys]; 

     NSMutableDictionary *addDictionary = [[NSMutableDictionary alloc] initWithCapacity:[keys count]]; 

     for (int j = 0; j < [keys count]; j++) { 

      id theObject = [inputArray[i] objectForKey:keys[j]]; // not need autorelease 

      if ([theObject isKindOfClass:[NSNumber class]]) { 

       [addDictionary setObject:[theObject stringValue] forKey:keys[j]]; 
       //[theObject release]; // not need release value here 

      }else if ([theObject isKindOfClass:[NSString class]]){ 
       [addDictionary setObject:[inputArray[i] objectForKey:keys[j]] forKey:keys[j]]; 
      } 

     } 
     [mutable addObject:addDictionary]; 
     [addDictionary release]; // release after not use 
    } 
    NSArray *returnArray = [[[NSArray alloc] initWithArray:mutable] autorelease]; // auto release for return value 

    [mutable removeAllObjects]; 
    [mutable release]; 
    return returnArray; 
} 
+0

谢谢ABáo我认为这已经完成了这项工作。 它给了我更多的问题与另一个AutoRelease池。 我会努力工作,并将其标记为正确,当我得到它的工作。 –

+0

@DavidP我编辑了答案//不需要autorelease或释放对象,你不拥有。尝试新代码 – larva

+0

谢谢@ABáo这真的让我走上了正确的道路。在这个函数之前,函数还有一个漏洞。 X-Code工具在NSJSONSerialization JSONObjectWithData方法中标识它。 我认为这是一个不同的问题。 –