4个小时过去了,我发现了问题。我将描述我是如何解决问题的XMLPerformance sample
。
问题出在NSAutoreleasePool
. 有@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool;
。当应用程序开始下载Top300 Paid Apps RSS
新线程时,使用[NSThread detachNewThreadSelector:@selector(downloadAndParse:) toTarget:self withObject:url];
. 所以在那个线程中我们应该保留本地自动释放池。它通过以下方式完成:
- (void)downloadAndParse:(NSURL *)url {
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
// initializing internet connection and libxml parser.
if (rssConnection != nil) {
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
}
// Release resources used only in this thread.
[downloadAndParsePool release];
self.downloadAndParsePool = nil;
}
所以downloadAndParse:
一切看起来都很好。现在让我们看一下在解析来自 RSS 的项目时调用的一种方法:
- (void)finishedCurrentSong {
// sending new item to delegate and other ...
countOfParsedSongs++;
// Periodically purge the autorelease pool. The frequency of this action may need to be tuned according to the
// size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but
// taking this action too frequently would be wasteful and reduce performance.
if (countOfParsedSongs == kAutoreleasePoolPurgeFrequency) {
[downloadAndParsePool release];
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
countOfParsedSongs = 0;
}
}
正如你看到的那样:
[downloadAndParsePool release];
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
所以正是这些行导致了异常。如果我评论他们一切都很好。
但我决定不仅要评论这些行,还要用块替换NSAutoreleasePool
,因为据说它更有效:- (void)downloadAndParse:(NSURL *)url
@autorelease
- (void)downloadAndParse:(NSURL *)url {
@autoreleasepool {
// initializing internet connection and libxml parser.
if (rssConnection != nil) {
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
}
// Release resources used only in this thread.
}
}
现在一切正常。我唯一没有解决的问题是:
// Periodically purge the autorelease pool. The frequency of this action may need to be tuned according to the
// size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but
// taking this action too frequently would be wasteful and reduce performance.
因此,如果有人对此问题有任何想法,可以发布另一个答案,并可能尝试更正确地解释错误修复。我很乐意接受这个答案。
谢谢。