Я предлагаю вам использовать Sync-Async Pattern для этой проблемы.
Вам необходимо реализовать два синхронных метода:
// Fetch the array of ID's
-(NSArray*)fetchItemIDsWithError:(NSError**)error;
// Fetch the item for a ID
-(Item*)fetchItemForID:(NSString*)itemID error:(NSError**)error;
Их реализация с использованием синхронного кода проста и тестируема. Вы можете легко использовать простые методы, такие как dataWithURL…
, stringWithContentsOfURL…
, sendSynchronousRequest…
или ASIHTTPrequest, и писать для этого прямые модульные тесты. Код также будет чрезвычайно прост в обслуживании и расширении, по сравнению с тем, как обычно заканчивается параллельный код.
Теперь на втором шаге создайте асинхронную оболочку, я бы использовал делегат и сигнатуру метода, подобную этой:
@protocol FetchItemsDelegate <NSObject>
-(void)didFetchItems:(NSArray*)array;
-(void)failedFetchItemsWithError:(NSError*)error;
@end
-(void)fetchItemsWithAsyncDelegate:(id<FetchItemsDelegate>)delegate;
У вас уже есть весь код, который делает то, что вам нужно, поэтому все, что вам нужно сделать, это устранить асинхронные части. Этот код будет хорошо отделен и прост. Пробалы не более этого:
-(void)fetchItemsWithAsyncDelegate:(id<FetchItemsDelegate>)delegate;
{
[self performSelectorInBackground:@selector(backgroundFetchItemsWithDelegate:)
withObject:delegate];
}
-(void)backgroundFetchItemsWithDelegate:(id<FetchItemsDelegate>)delegate;
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
BOOL success = YES;
NSMutableArray* items = [NSMutableArray array];
NSError* error = nil;
NSArray* itemIDs = [self fetchItemIDsWithError:&error];
if (itemIDs) {
for (NSString* itemID in itemIDs) {
Item* item = [self fetchItemForID:itemID
error:&error];
if (item) {
[items addObject:item];
} else {
success = NO;
break;
}
}
} else {
success = NO;
}
if (success) {
[delegate performSelectorOnMainThread:@selector(didFetchItems:)
withObject:[NSArray arraiWithArray:items]
waitUntilDone:NO];
} else {
[delegate performSelectorOnMainThread:@selector(failedFetchItemsWithError)
withObject:error
waitUntilDone:NO];
}
[pool release];
}
Я написал более длинную запись в блоге на эту тему здесь: http://blog.jayway.com/2011/04/28/sync-asyn-pair-pattern-easy-concurrency-on-ios/