iPhone内存崩溃:信号0

时间:2011-03-24 08:09:14

标签: iphone memory crash

我正在开发一款iPhone应用程序,可以显示地图中的一些图块。我有一个从互联网或文件系统加载tile的线程。这是一个无尽的线程

while( true ){ //get tile into cache }

Unfortunateley显示多个磁贴后,应用程序会因信号0而崩溃,这意味着内存不足...

我的想法是,在这个无尽的线程中,瓷砖被加载为自动释放,并且是自动释放的。

基本上我在无尽的线程中这样做:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
while( true ){
    UIImage * img = nil;
    NSFileHandle * tile = [NSFileHandle fileHandleForReadingAtPath:filePath];
    if( tile ){
        NSData * data = [tile readDataToEndOfFile];
        if( data ){
            img = [[UIImage alloc] initWithData:data];
            local = YES;
        }
    }
    if( img == nil ){
        NSURL * url = [NSURL URLWithString: [NSString stringWithFormat:@"http://tile.openstreetmap.org/%@.png", todoKey ] ];
        img = [[UIImage alloc] initWithData: [NSData dataWithContentsOfURL: url options:NSDataReadingMapped error:&error] ];
    }

    if( img != nil ){
        [cache addObject:img]; //cache is an array of tiles
    }

    [img release];
    [self cleanupCache]; //method to check if cache is full, and if so remove's objects from it
}
[pool release];

我认为autoreleasepool不会不时清理“死”引用,所有的tile都保存在内存中。当我检查仪器泄漏时,没有任何内存泄漏,但“实时内存”不断加起来..

任何想法都是为什么会发生这种情况以及如何阻止它?

3 个答案:

答案 0 :(得分:2)

你应该交换程序的前两行:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
while( true ){
  ...
  [pool release];
}

应该是

while( true ){
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  ...
  [pool release];
}

目前,在第一次循环之后,您创建的NSAutoreleasePool将被释放。在此之后,所有自动释放的对象将被添加到调用堆栈中更高的不同NSAutoreleasePool。我怀疑这个父自动释放池在你的程序运行时永远不会被释放。

答案 1 :(得分:0)

if( img != nil ){
 [cache addObject:img];

cache仍然保留您添加的所有对象的引用。你应该删除你不会使用的对象。

答案 2 :(得分:0)

我在代码中修复了缩进,希望我做对了。改进的凹痕使一个问题显而易见:

您正在发布已发布的对象,即您的池。

尝试在循环中移动NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

但最有可能的是你应该首先摆脱循环。

另一个问题是你没有将img设置为nil。如果在循环的第一次运行中存在有效的img,则代码将认为它对随后的所有其他循环运行有效。如果从缓存中移除img(并且对象img指向要取消分配),则在尝试将其添加到缓存时,会向已释放的对象发送一个retain。

在循环开头添加img = nil;