2012-11-25 180 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。