如何发信号通知一个线程等待下载完成,然后将数据传递给等待的线程

我有一个单身类从网上下载一些数据。 我正在调用GCD队列中其他类“A”的单例类的下载方法,并开始下载。 同时,我也在GCD Queue中从类“B”执行这个下载方法。 在这种情况下,我想通知class级“B”等待下载完成。 下载完成后,将下载的数据复制到“B”类。 这里我试图从两个类A和B下载相同的文件,否则在我的实现中没有问题。 这怎么可能?

在这里意味着我在不同的线程中调用相同的方法。 那么如何告诉线程B线程A中正在进行同样的文件下载,以及何时完成将线程B的数据传递给线程B

- (NSData *)Download:(NSString *)urlString{ // here I am doing all the downloading operations return data; } 

Downloader.h

 // Signature of a block that is called with the downloaded data from a URL // when the download is complete typedef (void)(^)(NSData *) DownloadCompletedBlock; // Public interface of a class that downloads data from URLs // Downloads take place on a private dispatch queue, which // downloads URLs one at a time // Previously downloaded URLs are cached in a dictionary // Every so often the cache should be processed to discard old // entries. This will stop the cache from growing too large. // Since all downloads happen on the same dispatch queue, // accesses to the cache are naturally serialized without the need // for a lock @interface Downloader : NSObject // Download the contents of a URL // When the download is complete downloadCompleted will // be executed on the callbackQueue to pass the downloaded // data as a result // This is the method that thread A should call - (void)download:(NSString *)URLString calbackQueue:(dispatch_queue_t)callbackQueue completionBlock:(DownloadCompletedBlock)downloadCompleted; // Download the contents of a URL blocking the thread that calls the // method - (NSData *)downloadBlocking:(NSString *)URLString; @end 

Downloader.m

 // Private implementation interface @interface Downloader () // The thread/queue on which all downloads take place @property (readwrite, atomic) dispatch_queue_t downloadQueue; // A cache of previously downloaded URLs @property (readwrite, atomic) NSMutableDictionary *cachedDownloads; // Download the contents of a URL and cache them - (NSData *)downloadAndCacheUrl:(NSString *)URLString; @end // Implementation @implementation Downloader // Create the download queue and cache - (id)init { self = [super init]; if (self) { downloadQueue = dispatch_queue_create("downloadQueue", NULL); self.cachedDownloads = [NSMutableDictionary dictionary]; } return self; } // Download the URL aynchronously on the download queue. // When the download completes pass the result to the callback queue // by calling downloadCompleted on the callback queue - (void)download:(NSString *)URLString calbackQueue:(dispatch_queue_t)callbackQueue completionBlock:(DownloadCompletedBlock)downloadCompleted { dispatch_async(self.downloadQueue, ^{ NSData *downloadedData = [self downloadAndCacheUrl:URLString]; dispatch_async(callbackQueue, ^{ downloadCompleted(downloadedData); }); }); } // Download the data blocking the calling thread // Use a block variable to store the result // Since the downloaded data is immutable, we do not need // to worry about synchronizing it or copying it // Use dispatch_sync to wait until the result is available // If the data is already in the cache because thread A downloaded it // then the cached data is used. // Since downloads happen serially, there is only ever one download happening // at a time so the download will only happen once - (NSData *)downloadBlocking:(NSString *)URLString { __block NSData *downloadedData = nil; dispatch_sync(self.downloadQueue, ^{ downloadedData = [self downloadAndCacheUrl:URLString]; }); return downloadedData; } // Download the content of a URL. If the data has already been // downloaded and cached, then use the cached value - (NSData *)downloadAndCacheUrl:(NSString *)URLString { NSURL *URL = [NSURL URLWithString:*)URLString]; NSData *downloadedData = [self.cachedDownloads objectForKey:URL]; if (downloadedData) { return downloadedData; } downloadedData = [NSData dataWithContentsOfURL:URL]; if (downloadedData) { [self.cachedDownloads setObject:downloadedData forKey:URL]; } } @end 

希望这已经够清楚了