我正在构建一个使用AFNetworking
重复调用Web服务的聊天应用程序。聊天屏幕不断轮询此服务以获取新的聊天消息。与服务相关的所有内容都可以正常工作,但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仍然冻结。我尝试使用后台线程,但也没有用。
答案 0 :(得分: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];
}];
应该没事。希望这有帮助!