你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ASIHTTPRequest的startAsynchronous調用EXC_BAD_ACCESS

ASIHTTPRequest的startAsynchronous調用EXC_BAD_ACCESS

編輯:IOS開發綜合
一個簡單的iOS應用,在主視圖控制器類中,實現了ASIHTTPRequest的委托方法- (void)requestFinished:(ASIHTTPRequest *)request和- (void)requestFailed:(ASIHTTPRequest *)request。 在這個類的viewDidLoad方法中,調用ASIHTTPRequest的異步請求。 請求對象的定義為retain,如@property(retain)ASIHTTPRequest* theRequest; 在- (void)viewDidLoad方法中,調用的類中的方法是這個。 - (IBAction)showCheckcode:(id)sender {         NSString *imgURL=@"https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=sjrand";         self.theRequest=[ASIHTTPRequest requestWithURL:[NSURL URLWithString:imgURL]] ;         self.theRequest.accessibilityLabel=@"imgCode";         [self.theRequest setTag:100];         [self.theRequest setValidatesSecureCertificate:NO];         //[theRequest applyCookieHeader];         self.theRequest.delegate=(id<ASIHTTPRequestDelegate>)self;         [self.theRequest startAsynchronous];    } 並且,在- (void)viewDidLoad方法中,又調用另外一個自定義類的方法,請求一個異步操作。而且這個類也實現了ASIHTTPRequest的委托方法。 應用一運行,就出現錯誤,在控制台中看到錯誤信息是EXC_BAD_ACCESS。   遇到問題第一個反應應該是,冷靜。 雖然這個問題很麻煩,明顯是和ASIHTTPRequest相關,而它是一個開源的框架,不是我所熟悉的。 ASIHTTPRequest的開發說不再維護它了,但ASIHTTPRequest也不失為一個非常好的網絡訪問框架,而且對於一般應用是足夠的。ASIHTTPRequest是基於MRC下,我的應用是ARC下,所以在將ASIHTTPRequest拖進應用包時,需要做一個簡單的調整。 1.選擇target,然後選擇Build Phases標簽,展開Compile Sources; 2.在所有和ASI..相關的文件後面的(Compile Flags)加入編譯選項”-fno-objc-arc”   對了,我的開發工具是XCODE4.5。這裡補充一下。   分析一下ASIHTTPRequest的框架,將ASIHTTPRequestConfig.h文件中配置調試項打開,再運行下。 雖然應用還是crash,但這回錯誤停在ASIHTTPRequest.m中一個方法上。   (void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders {    if ([self error] || [self mainRequest]) { return; }   --> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) {   問題出在delegate的設置上。   在stackoverflow.com上,有網友提出了兩個解決方法。   第一個,使用同一的delegate,並且應用一運行就初始化它。如果其他類要調用異步請求,將delegate發過去。 調用方法如下: - (void)sendUrl: (NSString *) restUrl withCallBack:(NSObject*) delegate; 然後,在delegate的實現方法中利用request的tag來標識來自哪一個類的異步調用。     第二個,使用block直接實現異步請求,拋棄delegate。   使用"setCompletionBlock:^"代替delegate的"setDidFinishSelector"。   request做一個設置就可以,比原來通過設置request.delegate再實現delegate的方法簡單多了。       [request setCompletionBlock :^{         // 請求響應結束,返回 responseString         NSString *responseString = [request responseString ]; // 對於 2 進制數據,使用 NSData 返回 NSData *responseData = [request responseData];         NSLog ( @"%@" ,responseString);     }];     [request setFailedBlock :^{         // 請求響應失敗,返回錯誤信息         NSError *error = [request error ];         NSLog ( @"error:%@" ,[error userInfo ]);     }];      可見第二個方法比第一個方便多了。在iOS5.0版本中,就可以使用block了。沒想到block這麼管用。         問題解決,按照個人慣例,需要簡單總結一下。 1、在ARC怎麼調用以前MRC開發的開源框架; 2、framework怎麼編譯,真機和模擬機的差別,release版和debug版的差別。這點在文檔中沒有提及,但也做了嘗試,雖然結果很失敗。 3、多線程,ASIHTTPRequest的異步請求就是多線程調用。 4、NSOperationQueue的一些基礎,但現在還不明白。 5、delegate的理解更透徹。
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved