Использование AsyncSocket со вторичными потоками на iPhone

Я использую AsyncSocket на iPhone для связи с сервером. AsyncSocket основан на циклах выполнения, но мое приложение основано на потоках. Это означает, что я запускаю новый поток для записи данных и жду, пока не будет получен ответ в том же потоке. Но я не могу вызвать метод AsyncSocket напрямую из другого потока, я должен использовать:

[self performSelectorOnMainThread:@selector(writeSomeData:) withObject:dataToWrite waitUntilDone:YES];

Это работает, но я не могу получить ответ от моего метода "writeSomeData:", вызванного таким образом, потому что PerformSelectorOnMainThread ничего не возвращает.

Метод writeSomeData: делает что-то вроде этого:

-(NSData *)writeData:(NSData *)dataToWrite {
    dataReceived = nil; // AsyncSocket writes data to this variable
    [asyncSocket writeData:dataToWrite withTimeout:-1 tag:0];
    [asyncSocket readDataToData:[@"<EOF" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    int counter = 0;
    while (dataReceived == nil && counter < 5) {
        // runLoop is [NSRunLoop currentRunloop]
        [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
        ++counter;
    }

    return [dataReceived copy];
}

Я мог бы получить ответ, обратившись к переменной класса «dataReceived», но в настоящее время ее содержимое изменено.

Может ли кто-нибудь сказать мне, как использовать AsyncSocket (или вообще, как работать с классами на основе циклов выполнения) в отдельных потоках, чтобы, если я вызываю метод этого класса, он блокировался до тех пор, пока метод не будет выполнен и не будет получен ответ?

Спасибо.


person Arthur    schedule 18.01.2011    source источник
comment
Зачем вам вообще нужен этот сценарий? Зачем создавать тему, если (по-видимому) первое, что вы делаете, это блокируете ее до какой-то более или менее произвольной даты в будущем? Почему бы не начать все это из потока с циклом выполнения и не отправить данные результата для обработки на NSOperationQueue или одном из глобальных параллельных dispatch_queue?   -  person danyowdee    schedule 01.01.2012


Ответы (1)


Попробуйте использовать GCD(Grand Central Dispatch), чтобы записать свои данные в отдельный поток, а затем вернуться к основному потоку в тот момент, когда данные были записаны. Вы можете сделать это следующим образом:

// call this on the main thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    NSData *data = [self writeData:dataToWrite];
    dispatch_async(dispatch_get_main_queue(), ^{
        // do something with the data on the main thread.
    });
});

Я надеюсь, что что-то вроде этого может помочь вам...

person Mihai Fratu    schedule 03.02.2012