Код в методе multipeer вызывается с задержкой в ​​20 секунд

Я использую многопользовательское подключение, и это один из методов:

-(void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress

{
NSLog(@"RECEIVING... %@ from peer: %@", progress, peerID);

UIProgressView *progressBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
progressBar.frame = CGRectMake(0, 200, 100, 20);
progressBar.progress = 0.5;
UIButton* btn = [BluetoothDeviceDictionary objectForKey:peerID];
[self.view addSubview:progressBar];

UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"Alert View Title" message:@"Alert View Text" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
[alertView show];
}

По какой-то ОЧЕНЬ СТРАННОЙ причине, когда вызывается этот метод, а я знаю, что он вызывается из-за ответа от NSLog, остальной код не выполняется. Предупреждение появляется через 20 секунд (более или менее) после появления NSLog, а представление хода выполнения никогда не появляется. Я не могу понять, почему. Это происходит для большинства методов в структуре многорангового подключения. Как это возможно?

РЕДАКТИРОВАТЬ: на самом деле появляется представление прогресса, но намного позже вызова метода


person Alessandro    schedule 02.10.2013    source источник


Ответы (1)


Возможно, метод делегата сеанса вызывается в фоновом потоке. Вызовы UIKit следует выполнять только в основном потоке, поэтому вам может потребоваться переместить код, взаимодействующий с UIKit, в другой метод, подобный этому:

- (void) updateUI {
    UIProgressView *progressBar = [[UIProgressView alloc];
    initWithProgressViewStyle:UIProgressViewStyleBar];
    progressBar.frame = CGRectMake(0, 200, 100, 20);
    progressBar.progress = 0.5;
    UIButton* btn = [BluetoothDeviceDictionary objectForKey:peerID];
    [self.view addSubview:progressBar];

    UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"Alert View Title" message:@"Alert View Text" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alertView show];
}

а затем вызовите его, используя:

-(void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress
{
    NSLog(@"RECEIVING... %@ from peer: %@", progress, peerID);
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
}
person Greg    schedule 02.10.2013
comment
+1. В документах MCSession важно: вызовы делегатов происходят в частной очереди операций. Если вашему приложению необходимо выполнить действие в конкретном цикле выполнения или очереди операций, его метод делегата должен явно отправлять или планировать эту работу. - person Marco; 04.12.2013