开发者

CFReadStream inside Multi-thread: the callback never called

A function multi-threaded by:

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

Called a callback function inside. Before multi-threading, the callback mechanism worked fine, but now the callback function is never called.

I have checked that the threaded-function works.

Below is the code, thank you very much.

+(void) download:(id) param{
    NSAutoreleas开发者_开发百科ePool *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];

}


IMPORTANT EDIT: My below answer was incorrect, it does not actually create and run the read stream in another thread! It just seems to actually schedule the read stream to run on the run loop found in the main thread instead.

  1. Call CFRunLoopGetCurrent()
  2. call CFRunLoopRun() after you get the loop on the new thread

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

    Is the correct code! Only perform the below if you wish to run code on the loop in the main thread.

I have found that you need to call CFRunLoopGetMain() instead of CFRunLoopGetCurrent()

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

would be the correct code to call in your case


Please check the readStream is Open

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

And If Open, try commenting NSAutoReleasePool I think some request value is autoreleased before the ReadStream open.

thanks,


it works now.

it is rather strange. the callback is never triggered. instead, i can read data from the original function after the ReadStream open.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜