Существует два способа решения вашей проблемы:
Самый простой выход
- это, как предполагает Дин, использование +[NSURLConnection sendSynchronousRequest:returningResponse:error:]
, поскольку вы уже находитесь в другом потоке.Это покрывает - я бы сказал - 80-90% времени, это действительно просто для реализации и Just Works ™.
Другой способ
только немного сложнее и имеетВы рассмотрели все случаи, когда первого метода недостаточно, посетив корень вашей проблемы:
NSURLConnection
работает совместно с runloop - и потоки, управляемые NSOperationQueue
, не обязательноиспользовать (или даже иметь!) связанный runloop.
При вызове +[NSURLConnection connectionWithRequest:delegate:]
неявно создаст runloop, если необходимо, это не заставит runloop фактически запускаться!
Это ваша ответственность , когда NSOperationQueue
, который вы используете, не является очередью, связанной с основным потоком.
Для этого измените реализацию fetchXMLWithCompletionHandler:
на внешний видпохож на следующее:
- (void)fetchXMLWithCompletionHandler:(WAFetchXMLHandler)block
{
self.xmlHandler = block; // Declare a @property for the block with the copy attribute set
self.mutableXMLData = [NSMutableData data]; // again, you should have a property for this...
self.currentConnection = [NSURLConnection connectionWithRequest:request delegate:self]; // having a @property for the connection allows you to cancel it, if needed.
self.connectionShouldBeRunning = YES; // ...and have a BOOL like this one, setting it to NO in connectionDidFinishLoad: and connection:didFailWithError:
NSRunLoop *loop = [NSRunLoop currentRunLoop];
NSDate *neverExpire = [NSDate distantFuture];
BOOL runLoopDidIterateRegularly = YES;
while( self.connectionShouldBeRunning && runLoopDidIterateRegularly ) {
runLoopDidIterateRegularly = [loop runMode:NSDefaultRunLoopMode beforeDate:neverExpire];
}
}
С этими небольшими изменениями, вы можете идти.Бонус: это действительно гибко и (в конечном итоге) многократно используется во всем вашем коде - если вы удалите разбор XML из этого класса и заставите свой обработчик просто взять NSData
, NSError
и (опционально) NSURLResponse
.
Поскольку вы, вероятно, не хотите, чтобы клиенты вашего загрузчика видели и, возможно, связывались со свойствами, которые я только что предложил добавить, вы можете объявить их в продолжении класса.