【发布时间】:2011-10-16 23:06:59
【问题描述】:
我正在尝试按照 XMLPerformance 示例制作我自己的 xml 解析器。到目前为止,我最难让自动释放池工作,我在重新创建池的那一刻就崩溃了。
我将问题缩小到这个测试用例:
PoolCrashTest.h
#import <SenTestingKit/SenTestingKit.h>
@interface PoolCrashTest : SenTestCase
{
@private
NSURLConnection *connection;
NSAutoreleasePool *downloadAndParsePool;
BOOL done;
}
@property (nonatomic, retain) NSURLConnection *connection;
@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool;
- (void)downloadAndParse:(NSURL *)url;
@end
PoolCrashTest.m
#import "PoolCrashTest.h"
@implementation PoolCrashTest
@synthesize downloadAndParsePool, connection;
- (void)downloadAndParse:(NSURL *)url {
done = NO;
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
self.connection = [[NSURLConnection alloc]
initWithRequest:theRequest delegate:self];
if (connection != nil) {
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
} while (!done);
}
self.connection = nil;
[downloadAndParsePool release];
self.downloadAndParsePool = nil;
}
#pragma mark NSURLConnection Delegate methods
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data {
[downloadAndParsePool drain];
在此行之后崩溃 ^
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
}
- (void)testPoolCrash
{
NSURL *dumpURL = [NSURL URLWithString:@"file:///some.xml"];
[NSThread detachNewThreadSelector:@selector(downloadAndParse:)
toTarget:self withObject:dumpURL];
sleep(10);
}
@end
有人可以解释如何正确清除线程中运行的 NSURLConnection 委托中的自动释放池吗?
我已尝试尽可能地遵循 XMLPerformance...我的目标是 Lion,主要是默认项目设置。
【问题讨论】:
-
在 didReceiveData 中跳过 drain/alloc pool 是否有效?此外,我认为连接会在您分配和保留(通过属性)时泄漏,然后只释放一次(将属性分配给 nil)。你应该在 alloc/init 之后自动释放它。
-
Mattias: 是的,我应该提到崩溃发生在 [[NSRunLoop currentRunLoop] runMode] 行,或者更确切地说,它是回溯中可用源代码的最后一行——顶部跟踪是 AutoreleasePoolPage::pop(void*) 方法,这让我觉得我试图释放其他地方创建的其他池。关于连接泄漏,您是对的——那是我草率的复制和粘贴。
标签: objective-c nsurlconnection nsautoreleasepool