是的,当然如果getAPI调用parseAPI,代码parseAPI将在与执行的线程相同的线程上getAPI执行,因此在您的示例中,在后台队列中。
要在最后将回调返回到主线程,请使用与 Apple 使用的相同技术,completionBlock您可以在多个 Apple API 上看到它们:只需将一个块(例如dispatch_block_t,或void(^)(NSError*)任何适合您需要的)作为参数传递给您的getAPI:方法,这将将它传递给parseAPI:它将依次传递给它,savetoDB:最后savetoDB:可以简单地用于dipatch_async(dispatch_get_main_queue, completionBlock);在主线程上调用此代码块(从方法传递到方法)。
注意:对于您的 getAPI,您可以使用 Apple 的sendAsynchronousRequest:queue:completionHandler:方法,该方法将在后台自动执行请求,然后调用指示的完成块NSOperationQueue(NSOperationQueue内部使用 GCD 的 dispatch_queue)。有关更多信息,请参阅有关NSOperationQueueGCD 和并发编程指南的文档以及 Apple 文档中所有非常详细的指南。
-(void)getAPI:( void(^)(NSError*) )completionBlock
{
NSURLRequest* req = ...
NSOperationQueue* queue = [[NSOperationQueue alloc] init]; // the completionHandler will execute on this background queue once the network request is done
[NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error)
{
if (error) {
// Error occurred, call completionBlock with error on main thread
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(error); });
} else {
[... parseAPI:data completion:completionBlock];
}
}];
}
-(void)parseAPI:(NSData*)dataToParse completion:( void(^)(NSError*) )completionBlock
{
... parse datatToParse ...
if (parsingError) {
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(error); });
} else {
[... savetoDB:dataToSave completion:completionBlock];
}
}
-(void)savetoDB:(id)dataToSave completion:( void(^)(NSError*) )completionBlock
{
... save to your DB ...
// Then call the completionBlock on main queue / main thread
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(dbError); }); // dbError may be nil if no error occurred of course, that will tell you everything worked fine
}
-(void)test
{
[... getAPI:^(NSError* err)
{
// this code will be called on the main queue (main thread)
// err will be nil if everythg went OK and vontain the error otherwise
}];
}