【问题标题】:Another memory leak using NSMutableArray使用 NSMutableArray 的另一个内存泄漏
【发布时间】:2012-02-01 09:58:19
【问题描述】:

我提供了有关代码的更多信息。 checkstatusthread() 每 5 秒调用一次。下面使用的ipItemsArray 对象存储来自服务器的 XML。

// XMLAppDelegate.h

@interface XMLAppDelegate : NSObject <UIApplicationDelegate> {
    NSMutableString *hostStr2;
    NSData *dataURL2;
    NSString *playlistdata;

}

@property (nonatomic, retain) NSMutableString *hostStr2;
@property (nonatomic, retain) NSData *dataURL2;
@property (nonatomic, retain) NSString *playlistdata;
@end

// XMLAppDelegate.m

-(void)checkstatusthread
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    hostStr2 = [[NSMutableString alloc] initWithFormat:@"http://%@/getplaylist.php?ip=%@",yourip,restip];

    dataURL2 = [NSData dataWithContentsOfURL: [ NSURL URLWithString: hostStr2 ]];  

    playlistdata = [[NSString alloc] initWithData:dataURL2 encoding: NSASCIIStringEncoding];

    ipItemsArray = [playlistdata componentsSeparatedByString:@"|^|"];

    [hostStr2 release]; 
    [playlistdata release];

    status =[ipItemsArray objectAtIndex:0];
    [status retain];

     if([[ipItemsArray objectAtIndex:0]isEqualToString:@"0001"])
     { 
        serverOutput1 =[ipItemsArray objectAtIndex:1];
        [serverOutput1 retain];

        nowplaying =[ipItemsArray objectAtIndex:2];    
        [nowplaying retain];

        tracklocation=[ipItemsArray objectAtIndex:3];
        [requestlocation retain];

        requestlocation=[ipItemsArray objectAtIndex:4];
        temp_app =[tracklocation intValue];


     }

        [serverOutput1 retain];
        [nowplaying retain];
        [serverOutput1 retain];
        [nowplaying retain];
        [tracklocation retain]; 
        [requestlocation retain];

        // checkstatus() called
        [self performSelectorOnMainThread:@selector(checkstatus) 
                           withObject:nil 
                        waitUntilDone:false];

    [pool drain];
}


- (void)dealloc {
    [dataURL2 release];
    [playlistdata release];
    [ipItemsArray release];
}

当我在 Xcode 4.2 中运行泄漏工具时,NSArray *ipItemsArray = [playlistdata componentsSeparatedByString:@"|^|"]; 行给了我内存泄漏。已经尝试了所有可能的事情,但觉得需要添加一些东西。谁能帮帮我。

这是泄漏对象的屏幕截图。我还注意到我的应用没有调用 Dealloc 方法。

【问题讨论】:

  • 完成后你会发布 playlistdata 和 hostStr2 吗?
  • 为什么要保留两次身份?
  • 我已删除状态保留行之一。那是错误打印的。
  • 我使用自动引用计数来自动管理对象,就像我使用 XCode 4.2 一样。我的问题解决了,没有泄漏。我不确定这在旧版本的 iOS 上是否可以正常工作,以及它是否会得到 Apple 的批准。

标签: iphone xcode memory-leaks nsmutablearray


【解决方案1】:

泄漏的对象是“状态”。我推断它是一个 iVar。当你这样做时:

 status =[ipItemsArray objectAtIndex:0];
[status retain];

第二次执行这些行时,之前存储在 status 中的值未正确释放,因此发生泄漏。理想情况下,您应该这样做:

if(status) {
    [status release];
}
status =[ipItemsArray objectAtIndex:0];
[status retain];

这将解决仪器中显示的泄漏问题。 (假设没有使用 ARC)

【讨论】:

  • 其他 iVar 也必须这样做。否则使用保留属性并使用 self.status 访问它们,依此类推。这种情况下可以直接赋值,不必释放之前的值
【解决方案2】:

实际上分析器将您指向这行代码:

NSMutableString *hostStr2 = [[NSMutableString alloc] initWithFormat:@"http://   %@/getplaylist.php?ip=%@",yourip,restip];

您已分配但尚未释放。

你需要释放它。

【讨论】:

  • 播放列表数据也没有发布。
  • playlistdata 是班级级别,所以我没有指出。
  • 我将释放所有三个对象。但它仍然显示内存泄漏。我需要使用其他一些类或任何其他解决方案吗?
  • 三个??您要释放的第三个对象是什么……只有 hostStr2 和 playlistdata 被分配并需要释放。 hoststr2 是一个局部变量,不能合理地在此函数之外释放。如果 playlistdata 只是在类 dealloc 中释放,但是这个函数被多次调用,也会泄漏。我们需要比这四行更多的上下文来帮助解决这个问题。
  • @AdilSoomro:我已经编辑了这个问题并提供了更多代码来帮助您更好地理解它。请看一下。
【解决方案3】:

你所做的一切都是正确的。并非 Leaks Instrument 显示的所有泄漏当前都是泄漏。

我建议您首先使用 Clang Analyzer XCode -> Products -> Analyse。这向您显示了一些潜在的泄漏。然后你应该使用Heapshot Analysis http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

【讨论】:

  • 谢谢。分析显示我没有问题。我将尝试此处给出的链接并使用此方法并回来。
  • 通过使用Allocations工具,Mark Heap分析再次指向这行代码。 NSArray *ipItemsArray = [playlistdata componentsSeparatedByString:@"|^|"];
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 2011-01-21
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多