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.
- Call CFRunLoopGetCurrent()
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.
精彩评论