2012-11-25 147 views
2

我读过关于CFRunLoop,但仍然有点困惑。我来到一个交叉的一段代码,我想澄清我自己:iOS:CFRunLoopRun()函数混淆

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:url]]]; 
[request setHTTPMethod:@"POST"]; 
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; 
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
[request setHTTPBody:postData]; 
[[NSURLConnection alloc]initWithRequest:request delegate:self]; 

CFRunLoopRun(); 

因此,假设这是所有被称为主线程上,将它阻塞主线程?或者它会通过CFRunLoopRun()函数调用产生一个新线程?

谢谢!

+0

这通常在请求在后台线程中进行时运行。 – iDev

回答

3

假设这是从主线程调用的,没有任何理由调用CFRunLoopRun,因为默认运行循环应该已经在运行。

您使用NSURLConnection的方式不会阻止调用线程。它可能在内部产生额外的线程,但你并不真的必须在意这一点。 initWithRequest:delegate:将立即返回并且稍后调用委托方法(当收到响应,数据被加载等时)。

+0

有趣。因此,在代理的connectionDidFinishLoading中,我看到以下调用: CFRunLoopStop(CFRunLoopGetCurrent()); 会根据您的答案导致任何问题吗?它会尝试停止默认运行循环吗? – ymotov

+0

我猜想你正在看的代码被设计为在辅助线程上运行。根据我对“CFRunLoopRun”如何工作的理解,“CFRunLoopStop”应该只停止由“CFRunLoopRun”创建的嵌套运行循环,但我可能是错的。在主线上,这些东西都没有什么意义。 – omz

+0

这就是我的想法,但需要确认。谢谢。 – ymotov

8

实际上有一个情况是有道理的。创建递归运行循环时(这是执行该行时会发生的情况):

可以递归运行运行循环。换句话说,您可以调用CFRunLoopRun,CFRunLoopRunInMode或任何NSRunLoop方法 来从输入源012或者定时器的处理程序例程中启动运行循环。这样做时,可以使用任何模式运行嵌套运行循环,包括外部运行循环使用的模式。

因此,问题是做这样的事情:

- (NSMutableData *)serverRequest 
{ 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:[NSURL URLWithString:[NSString stringWithFormat:url]]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setHTTPBody:postData]; 
    [[NSURLConnection alloc]initWithRequest:request delegate:self]; 

    CFRunLoopRun(); 
    return _returnDataFromServer; 
} 

所以该方法serverRequest将不会退出,直到你真正停止RunLoop:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    // Append the new data to the instance variable you declared 
    [_connectionData appendData:data]; 

    CFRunLoopStop(CFRunLoopGetCurrent()); 
} 

我不会做到这一点,最好将这件作品传递给工作线程。还有其他一些方法可以实现这一点,而不是使用Run Loop。