CFReadStream里面的多线程:从不调用回调

时间:2011-07-14 12:51:28

标签: iphone multithreading http callback websocket

一个多线程函数:

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

在里面调用一个回调函数。在多线程之前,回调机制运行良好, 但现在永远不会调用回调函数。

我已经检查过thread-function是否正常工作。

下面是代码,非常感谢。

+(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 个答案:

答案 0 :(得分:1)

重要编辑:我的下面的答案不正确,它实际上并没有在另一个线程中创建和运行读取流!它实际上似乎实际上安排读取流在主线程中找到的运行循环上运行。

  1. 致电CFRunLoopGetCurrent()
  2. 在新线程上获得循环后调用CFRunLoopRun()

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

    是正确的代码!如果您希望在主线程中的循环上运行代码,请仅执行以下操作。

  3. 我发现你需要调用CFRunLoopGetMain()而不是CFRunLoopGetCurrent()

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

    将是您的案例中正确的代码

答案 1 :(得分:0)

请检查readStream是否已打开

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

如果是Open,请尝试评论NSAutoReleasePool我认为在ReadStream打开之前会自动释放一些请求值。

感谢,

答案 2 :(得分:0)

现在有效。

这很奇怪。 永远不会触发回调。 相反,我可以在ReadStream打开后从原始函数中读取数据。