2016-07-15 60 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方法中標識它。 我認爲這是一個不同的問題。 –