将NSURLConnection委托回调引入正确的线程

时间:2012-06-19 17:51:20

标签: objective-c ios multithreading delegates grand-central-dispatch

当我编写代码时,似乎无法使Delegate回调工作。我试图使用NSURLConnection调用远程服务器来获取access_token。 access_token在connection:didReceiveResponse:delegate中收到。在我发布它之前,这不是问题。我以为我正在为我的代表传递正确的对象,但它没有达到连接:didReceiveResponse:

任何人都可以看到为什么连接:didReceiveResponse:在我调用线程时没有调用LoginViewController?感谢。

LoginViewController.m

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSString *access_token = [self getTokenFromResponse: response]; 
    [self.delegate didGetAccessToken:access_token]; 
}

- (void)fetchAccessTokenNoUI
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString: @"www.mysite.com"]];   
    [NSURLConnection connectionWithRequest:request delegate:self];
} 

AccessToken.h

@interface AccessToken : NSObject
@property (atomic, strong) LoginViewController *loginViewController; // doing this to try to keep it persistent
- (void) fetchAccessTokenWithDelegate: (id <LoginDelegate>)delegate;
@end

AccessToken.m

- (void) fetchAccessTokenWithDelegate: (id < LoginDelegate >)delegate
{
    dispatch_queue_t downloadQueue = dispatch_queue_create("Fetch access_token queue", NULL);
    dispatch_async(downloadQueue, ^ {
        // this works fine if I don't do it in a queue
        self.loginViewController = [[LoginViewController alloc] init];
        self.loginViewController.delegate = delegate;
        [self.loginViewController fetchAccessTokenNoUI];

    });
    dispatch_release(downloadQueue);
}

CallingClass.m

- (void)didGetAccessToken:(NSString *)access_token
{
    if (!access_token)
    {
        LoginViewController *userProfileViewController = [[LoginViewController alloc] init];
        userProfileViewController.delegate = self;
        [self.navigationController pushViewController:userProfileViewController animated:YES];
    }
}
- (IBAction)favourite:(id)sender 
{
    AccessToken *accessToken = [[AccessToken alloc] init];
    [accessToken fetchAccessTokenWithDelegate:self];

}

2 个答案:

答案 0 :(得分:0)

您是否设置了存根来实现所需的协议方法,

-(void)connectionDidFinishLoading:(NSURLConnection *)connection;
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

因为我有类似的问题在实施后就消失了。

答案 1 :(得分:0)

经过一些研究,我找到了解决方案。

我实际上并不需要AccessToken.h / m。我以为NSURLConnection调用会阻止我的UI线程。但NSURLConnection connectionWithRequest:delegate:自动在一个单独的线程中运行。

所以我要做的就是删除AccessToken.h和AccessToken.m。然后,在CallingClass.m中,我改变了favourte:to

- (IBAction)favourite:(id)sender 
{
    LoginViewController *loginViewController = [[LoginViewController alloc] init];
    [loginViewController fetchAccessTokenWithDelegate:self];

}

就是这样!根本不需要dispatch_queue_t。