В приложении воспользуйтесь потоками. Это делается примерно так:
— (void) downloadNewFile:(id)paramObject{
@autoreleasepool {
NSString *fileURL = (NSString *)paramObject;
NSURL *url = [NSURL URLWithString: fileURL];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *downloadedData =
[NSURLConnection sendSynchronousRequest: request
returningResponse:&response
error:&error];
if ([downloadedData length] > 0){
/* Загрузка завершена. */
} else {
/* Ничего загружено не было. Проверьте значение Error. */
}
}
}
— (void)viewDidLoad {
[super viewDidLoad];
NSString *fileToDownload = @"http://www.OReilly.com";
[NSThread detachNewThreadSelector:@selector(downloadNewFile:)
toTarget: self
withObject: fileToDownload];
}
Любое приложение iOS состоит из одного или нескольких потоков. В операционной системе iOS 5 у обычного приложения с одним контроллером вида изначально может быть от одного до пяти потоков, создаваемых системными библиотеками, с которыми связано приложение. Для вашего приложения будет создаваться как минимум один поток независимо от того, собираетесь вы пользоваться несколькими потоками или нет. Этот поток называется основным потоком пользовательского интерфейса и прикрепляется к главному рабочему циклу.
Чтобы оценить, насколько полезны потоки, проведем эксперимент. Предположим, у нас есть три цикла:
— (void) firstCounter{
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"First Counter = %lu", (unsigned long)counter);
}
}
— (void) secondCounter{
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Second Counter = %lu", (unsigned long)counter);
}
}
— (void) thirdCounter{
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Third Counter = %lu", (unsigned long)counter);
}
}
Очень просто, правда? Все циклы проходят от 0 до 1000, выводя на консоль номера счетчиков. Теперь предположим, что вы хотите, как обычно, запустить эти счетчики:
— (void) viewDidLoad{
[super viewDidLoad];
[self firstCounter];
[self secondCounter];
[self thirdCounter];
}
Этот код не обязательно должен находиться в методе viewDidLoad контроллера вида.
Теперь откройте окно консоли и запустите это приложение. Вы увидите, как сначала целиком выполнится первый счетчик, потом второй и, наконец, третий. Это означает, что данные циклы выполняются в одном и том же потоке. Каждый счетчик блокирует исполнение остального кода, относящегося к потоку, пока этот счетчик не завершит свой цикл.
А что, если бы мы захотели запустить все счетчики одновременно? Разумеется, для каждого из них нам пришлось бы создать отдельный поток. Но подождите! Мы ведь уже знаем, что прямо при загрузке приложение само создает для нас потоки. Кроме того, весь код, который мы уже успели создать для приложения, когда бы он ни был написан, исполняется в полученном потоке. Итак, мы уже создали по потоку для первого и второго счетчиков, а третий счетчик будет работать в главном потоке:
— (void) firstCounter{
@autoreleasepool {
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"First Counter = %lu", (unsigned long)counter);
}
}
}
— (void) secondCounter{
@autoreleasepool {
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Second Counter = %lu", (unsigned long)counter);
}
}
}
— (void) thirdCounter{
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Third Counter = %lu", (unsigned long)counter);
}
}
— (void)viewDidLoad {
[super viewDidLoad];
[NSThread detachNewThreadSelector:@selector(firstCounter)
toTarget: self
withObject: nil];
[NSThread detachNewThreadSelector:@selector(secondCounter)
toTarget: self
withObject: nil];
/* Этот код запускаем в главном потоке. */
[self thirdCounter];
}
У метода thirdCounter нет автоматически высвобождаемого пула, поскольку он не работает в новом открепленном потоке. Этот метод будет выполняться в главном потоке приложения, а главный поток располагает автоматически высвобождаемым пулом. Данный пул создается автоматически при написании любого приложения Cocoa Touch.
Ближе к концу кода мы видим вызовы селектора detachNewThreadSelector, предназначенные для запуска первого и второго счетчиков в отдельных потоках. Теперь, запустив приложение, вы увидите в окне консоли примерно следующий вывод:
Читать дальше
Конец ознакомительного отрывка
Купить книгу