Крейг прав, когда говорит, что вы переиздаваете свой пул. В среде без GC release
и drain
имеют одинаковый эффект. В среде GC release
- это неоперабельный для любого объекта , поэтому вместо него следует использовать drain
. Я бы просто использовал drain
.
Тем не менее, NSAutoreleasePool
объекты на самом деле не вещи, которые вы должны делать свойством своего класса; они будут работать лучше для вас, если вы ограничите их использование лексической областью. Есть несколько способов использовать пул в коде, который вы разместили выше, и этого будет достаточно.
Помните, что при вращении цикла выполнения он будет входить и выходить из вызова, чтобы запустить цикл выполнения в обычных режимах; так что вы можете сделать это вместо:
if (connection != nil) {
do {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
[pool drain];
} while (!done);
}
и вы будете сливать любые автоматически выпущенные объекты, созданные в конкретном цикле цикла выполнения. Поскольку обратный вызов делегата соединения будет вызываться из-за этого вызова цикла выполнения, все автоматически выпущенные объекты, созданные в обратном вызове делегата, будут очищены при сливе этого пула.
Если вам это неудобно, вы можете поместить пул в ваш метод делегата в зависимости от того, сколько работы ваш метод делегата может выполнять:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Do whatever work you want here
[pool drain];
}
И в вашем случае это будет иметь примерно такой же эффект.
Я бы настоятельно рекомендовал сделать что-то похожее на мой первый пример выше и устранить поведение пула авто-выпусков, которое у вас есть сейчас. Хранение NSAutoreleasePool
объектов в одной лексической области облегчает все, от отладки до безопасной обработки исключений, когда это становится необходимым.