【问题标题】:AFNetworking freezes other actionsAFNetworking 冻结其他操作
【发布时间】:2013-07-24 08:57:55
【问题描述】:

我正在构建一个聊天应用程序,它使用AFNetworking 反复调用网络服务。聊天屏幕不断轮询此服务以获取新的聊天消息。与服务相关的所有内容都可以正常工作,但 UI 一直冻结,并且所有按钮都不起作用。

代码如下:

- (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];
}

我每次都重新加载表格视图,但 UI 仍然冻结。我尝试使用后台线程,但也没有用。

【问题讨论】:

  • 尝试在后台线程中调用此方法。
  • 注意是AFNetworking 不是AFINetworking
  • 您的代码看起来不错。它应该可以异步工作。如果您反复调用此 Web 服务,那么我认为您的代码一次又一次地调用此 Web 服务,其结果是您的代码以递归方式运行(可能是某处方法以递归方式运行的机会,是的,您在 main 上处理大量数据线)。递归代码冻结您的应用程序。检查你的类和方法调用层次结构。
  • 这个方法是做什么的[self GetAllIncomingMessages];
  • 从服务器获取一些简单的 json 数据..

标签: iphone ios objective-c web-services ipad


【解决方案1】:

我知道这是一个老问题,但我只是碰到了它。仅供参考,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];
                                                }];

应该没问题。希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多