在iOS網絡編程中,我們經常會遇到線程的同步和異步問題,同時為了對異步請求更加精准豐富的控制,我們還常常在iOS中使用請求隊列,下面就來談談iOS開發中同步、異步以及請求隊列的使用方法。
1. 同步意為着線程阻塞,在主線程中使用此方法會不響應任何用戶事件。所以,在應用程序設計時,大多被用在專門的子線程增加用戶體驗,或用異步請求代替。
1
2
3
4
5
6
7
8
9
10
|
- (IBAction)grabURL:(id)sender
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if
(!error) {
NSString *response = [request responseString];
}
}
|
用 requestWithURL 快捷方法獲取 ASIHTTPRequest 的一個實例
startSynchronous 方法啟動同步訪問
由於是同步請求,沒有基於事件的回調方法,所以從 request的error 屬性獲取錯誤信息
responseString,為請求的返回 NSString 信息 *
注意:在這里我發現NsUrlRequset和connect系統Api就可以配合做到效果。也不需要到移植開源代碼
2. 異步請求的好處是不阻塞當前線程,但相對於同步請求略為復雜,至少要添加兩個回調方法來獲取異步事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
- (IBAction)grabURLInBackground:(id)sender
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (
void
)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (
void
)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
|
與上面不同的地方是指定了一個 “delegate”,並用 startAsynchronous 來啟動網絡請求
在這里實現了兩個 delegate 的方法,當數據請求成功時會調用 requestFinished,請求失敗時(如網絡問題或服務器內部錯誤)會調用 requestFailed。
PS: 異步請求一般來說更常用一些,而且里面封裝都挺不錯的,至少比symbian等平台方便的多,而且還可以修改源代碼。多數這個跟隊列混合封裝來達到圖片和異步下載包的目的(已實現)。
3. 請求隊列提供了一個對異步請求更加精准豐富的控制。如:可以設置在隊列中同步請求的連接數。往隊列里添加的請求實例數大於 maxConcurrentOperationCount 時,請求實例將被置為等待,直到前面至少有一個請求完成並出列才被放到隊列里執行。這也適用於當我們有多個請求需求按順序執行的時候(可能是業務上的需 要,也可能是軟件上的調優),僅僅需要把 maxConcurrentOperationCount 設為“1”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
- (IBAction)grabURLInTheBackground:(id)sender
{
if
(![self queue]) {
[self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
}
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[[self queue] addOperation:request];
//queue is an NSOperationQueue
}
- (
void
)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
}
- (
void
)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
|