Ответ 1
Прошло 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.
Итак, если у кого-нибудь есть мысли об этой проблеме, можно опубликовать еще один ответ и, возможно, попытайтесь объяснить правильность исправления ошибок. Я буду рад принять этот ответ.
Спасибо.