2013-07-24 52 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]; 
               }]; 

而且应该罚款。希望这个帮助!