2013-07-24 86 views
1

我建立一個聊天應用程序,它使用AFNetworking重複調用的Web服務。聊天屏幕不斷地輪詢此服務以獲得新的聊天消息。與服務相關的一切工作正常,但UI保持凍結,並且沒有任何按鈕正在工作。AFNetworking凍結等措施

下面是代碼:

- (void)GetAllIncomingMessages 
{ 
    NSURL *url = [NSURL URLWithString:weatherUrl]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
    AFJSONRequestOperation *operation = 
    [AFJSONRequestOperation JSONRequestOperationWithRequest: request 
                success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

                 [self ParseJson:(NSDictionary *)JSON]; 
                 [self GetAllIncomingMessages]; 


                } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) 

                { 
                 [self GetAllIncomingMessages]; 
                 UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error " 
                            message:[NSString stringWithFormat:@"%@",error] 
                            delegate:nil 
                          cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
                 [av show]; 
                }]; 
    [operation setAuthenticationChallengeBlock: 
    ^(NSURLConnection* connection, NSURLAuthenticationChallenge* challenge) 
    { 
     if([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodHTTPBasic) 
     { 
      if([challenge previousFailureCount] > 0) 
      { 
       // Avoid too many failed authentication attempts which could lock out the user 
       [[challenge sender] cancelAuthenticationChallenge:challenge]; 
      } 
      else 
      { 
       [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistenceForSession] forAuthenticationChallenge:challenge]; 
      } 
     } 
     else 
     { 
      // Authenticate in other ways than NTLM if desired or cancel the auth like this: 
      [[challenge sender] cancelAuthenticationChallenge:challenge]; 
     } 
    }]; 
    [operation start]; 
} 

我重裝每次表視圖,而且用戶界面仍然凍結。我嘗試使用後臺線程,並沒有工作。

+1

試圖調用在後臺線程此方法。 –

+0

注意它是'AFNetworking'不'AFINetworking' –

+0

你的代碼看起來很好。它應該有異步工作。如果反覆調用這個Web服務的話,我覺得你的代碼搞一次又一次地調用這個Web服務,其結果遞歸運行(您的代碼可以遞歸某處運行方法的機會呀你處理大量的主數據線)。遞歸代碼凍結您的應用程序。檢查你的類和方法調用層次結構。 – Tirth

回答

2

我知道這是一個老問題,但我只是碰到了它。只是FYI AFNetworking使用調度的異步隊列來執行連接操作,並將在主隊列中檢索到的NSData的JSON格式返回給您(您可能已經知道)。所以AFNetworking絕對不是問題。

我的建議是嘗試執行ParseJson:和GetAllIncomingMessages:在獨立的線程或派遣一個異步排隊你自己,你會看到你的UI不再結冰。

喜歡的東西:

static dispatch_queue_t your_app_queue() { 
    static dispatch_once_t onceToken; 
    static dispatch_queue_t _myQueue; 
    dispatch_once(&onceToken, ^{ 
     _myQueue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_SERIAL); 
    }); 
    return _myQueue; 
} 

AFJSONRequestOperation *operation = 
[AFJSONRequestOperation JSONRequestOperationWithRequest: request 
               success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

                __block myClass = self; 
                dispatch_async(your_app_queue(), ^{ 

                 [myClass ParseJson:(NSDictionary *)JSON]; 
                 [myClass GetAllIncomingMessages]; 
                }); 
               } 
               failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){ 

                __block myClass = self; 
                dispatch_async(your_app_queue(), ^{ 

                  [myClass GetAllIncomingMessages]; 
                  dispatch_async(dispatch_get_main_queue(), ^{ 

                   UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error " 
                              message:[NSString stringWithFormat:@"%@",error] 
                              delegate:nil 
                            cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
                   [av show]; 
                  }); 
                }); 
               }]; 

或者:

AFJSONRequestOperation *operation = 
[AFJSONRequestOperation JSONRequestOperationWithRequest: nil 
               success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

                [self performSelectorInBackground:@selector(ParseJson:) withObject:JSON]; 
                [self performSelectorInBackground:@selector(GetAllIncomingMessages) withObject:nil]; 
               } 
               failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){ 

                [self performSelectorInBackground:@selector(GetAllIncomingMessages) withObject:nil]; 

                UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error " 
                           message:[NSString stringWithFormat:@"%@",error] 
                           delegate:nil 
                         cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
                [av show]; 
               }]; 

而且應該罰款。希望這個幫助!