CFReadStream внутри многопоточности: обратный вызов никогда не вызывается - PullRequest
0 голосов
/ 14 июля 2011

Функция многопоточная:

[NSThread detachNewThreadSelector:@selecter(download:) toTarget:..... withObject:....];

Вызывается функция обратного вызова внутри.До многопоточности механизм обратного вызова работал нормально, но теперь функция обратного вызова никогда не вызывается.

Я проверил, что многопоточная функция работает.

Ниже приведен код, большое спасибомного.

+(void) download:(id) param{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  

    while(true){
        NSLog(@"Thread going ");
        NSArray* ary = [Data_Center sharedData_Center]->data;

        for(int i = 0; i < [ary count]; i++) {
            NSLog(@"code = %@", code);
            ..........            
            NSURL* url1 = [NSURL URLWithString:str_code];

            [str_code length];


            CFStreamClientContext dataStreamContext = {0, self, NULL, NULL, NULL};

            CFHTTPMessageRef message = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), (CFURLRef)url1, kCFHTTPVersion1_1);
            CFHTTPMessageSetBody(message, (CFDataRef)(CFSTR("")));

            CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, message);
            CFOptionFlags events = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;

            // print "client = 1" here                    
            //NSLog(@"client = %d" , CFReadStreamSetClient(readStream, events, readStreamEventCallBack, & dataStreamContext));


            if(CFReadStreamSetClient(readStream, events, readStreamEventCallBack, & dataStreamContext)) {
                CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
            }


            CFReadStreamOpen(readStream);
        }


        [NSThread sleepForTimeInterval:10];
    }
    [pool release];

}

Ответы [ 3 ]

1 голос
/ 03 марта 2016

ВАЖНОЕ РЕДАКТИРОВАНИЕ: Мой ответ ниже был неверным, он фактически не создает и не запускает поток чтения в другом потоке! Похоже, что на самом деле он запланировал запуск потока чтения в цикле выполнения, который находится в основном потоке.

  1. Вызов CFRunLoopGetCurrent ()
  2. вызов CFRunLoopRun () после получения цикла в новом потоке

    if(CFReadStreamSetClient(readStream, events, readStreamEventCallBack, & dataStreamContext)) {
     CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
     CFRunLoopRun();
    }
    

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

Я обнаружил, что вам нужно вызвать CFRunLoopGetMain () вместо CFRunLoopGetCurrent ()

 if(CFReadStreamSetClient(readStream, events, readStreamEventCallBack, & dataStreamContext)) {
     CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetMain(), kCFRunLoopCommonModes);}

будет правильным кодом для вызова в вашем случае

0 голосов
/ 19 июля 2011

теперь работает.

это довольно странно. обратный вызов никогда не срабатывает. вместо этого я могу читать данные из исходной функции после открытия ReadStream.

0 голосов
/ 18 июля 2011

Пожалуйста, проверьте, что readStream открыт

if (CFReadStreamOpen((CFReadStreamRef)readStream)) {
    NSLog(@"CFReadStreamOpen Sucessfully");
}
else {
    NSLog(@"Unable to start HTTP connection");
}

И если Open, попробуйте комментировать NSAutoReleasePool. Я думаю, что некоторое значение запроса автоматически высвобождается перед открытием ReadStream.

спасибо,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...