2

我读过关于 CFRunLoop 但仍然有点困惑。我遇到了一段我想为自己澄清的代码:

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() 函数调用产生一个新线程?

谢谢!

4

2 回答 2

9

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

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

所以关键是做这样的事情:

- (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。

于 2013-12-13T17:32:24.090 回答
3

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

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

于 2012-11-25T04:18:38.390 回答