dispatch_semaphore_wait останавливает ВСЕ потоки в приложении iPhone

#iphone #objective-c #asynchronous #semaphore #nsstream

#iPhone #цель-c #асинхронный #семафор #nsstream

Вопрос:

Я использую dispatch_semaphore_wait, чтобы остановить мой текущий поток, но похоже, что он останавливает все мои потоки.

Код:

 SampleReader *reader = [[SampleReader alloc] initWithHostname:hostname andFilePath:filepath];
reader.endHandler = endHandler;

[reader start];

dispatch_semaphore_wait(reader->mSem, DISPATCH_TIME_FOREVER);
 

Мой метод запуска имеет что-то вроде:

 mFileStream = [[NSOutputStream outputStreamToFileAtPath:[fileurl path] append:FALSE] retain];
[mFileStream open];

mNetworkStream = (NSInputStream *)CFReadStreamCreateWithFTPURL(NULL, (CFURLRef)ftpurl);
mNetworkStream.delegate = self;
[mNetworkStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[mNetworkStream open];
 

Я получаю обратный вызов в одном из методов делегирования, в котором я сигнализирую семафору

 - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{

  switch (eventCode)
  Case NSStreamEventErrorOccurred:
                    dispatch_semaphore_signal(mSem);
        break;
    case NSStreamEventEndEncountered:
        dispatch_semaphore_signal(mSem);
        break;
 

}

Однако, когда я отправляю ожидание по семафору, метод делегирования не вызывается. Он вызывается только тогда, когда я закомментирую строку

  //dispatch_semaphore_signal(mSem);
 

Любая помощь будет принята с благодарностью.

Ответ №1:

Если вы вызываете [reader start] из своего основного потока, то вы создаете взаимоблокировку. Ваш поток здесь ассоциируется с основным потоком:

 [mNetworkStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
 

Это означает, что для его работы должен вращаться основной цикл выполнения. Однако, если dispatch_semaphore_wait это происходит в основном потоке, вы останавливаете цикл выполнения и не позволяете потоку обрабатывать свои события.

Я не понимаю, как комментирование dispatch_semaphore_signal могло бы сделать что-то еще, кроме того, чтобы wait никогда не возвращаться.