如何在这种情况下管理块

时间:2016-05-21 10:57:48

标签: ios objective-c objective-c-blocks

我正在为Instagram API实现帮助程序类。

我有一种获取访问代码的方法:

-(void) makeAuthenticateRequestWithBlock: (completionBlock) block {
  if (![self.viewController.view.subviews containsObject: self.webView]) {
    [self.viewController.view addSubview: self.webView];
  }
  if (!self.isUserAuthinticated && self.isAvailableAllRequredData) {
    NSString * fullURL = [NSString stringWithFormat: @ "%@?client_id=%@&redirect_uri=%@&response_type=token&scope=likes+comments+basic+public_content+follower_list", KAUTHURL, self.clientId, self.redirectURL];
    NSURL * url = [NSURL URLWithString: fullURL];
    NSURLRequest * request = [NSURLRequest requestWithURL: url];
    [self.webView loadRequest: request];
    self.block = block;
  }
} 

typedef void(^completionBlock) (BOOL success);是一个块,我有:

@property (copy, nonatomic) completionBlock block;

在webview委托方法中。

-(BOOL) webView: (UIWebView * ) webView shouldStartLoadWithRequest: (NSURLRequest * ) request navigationType: (UIWebViewNavigationType) navigationType {
  NSString * urlString = [
    [request URL] absoluteString
  ];
  NSLog(@ "URL STRING : %@ ", urlString);
  NSArray * UrlParts = [urlString componentsSeparatedByString: [NSString stringWithFormat: @ "%@/", self.redirectURL]];
  if ([UrlParts count] > 1) {
    // do any of the following here
    urlString = [UrlParts objectAtIndex: 1];
    NSRange accessToken = [urlString rangeOfString: @ "#access_token="];
    if (accessToken.location != NSNotFound) {
      NSString * strAccessToken = [urlString substringFromIndex: NSMaxRange(accessToken)];
      NSLog(@ "access token = %@ ", strAccessToken);
      [self.webView removeFromSuperview];
      [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
      [
        [NSUserDefaults standardUserDefaults] setValue: strAccessToken forKey: kAccessToken
      ];
      [
        [NSUserDefaults standardUserDefaults] synchronize
      ];
      self.isUserAuthinticated = true;
      self.block(true);
    }
    return NO;
  }
  return YES;
}

一切正常。

现在,当我向Instagram API发送请求时,我会检查用户是否已通过身份验证。

-(void) getInformationOfOwnWithCompletionBlock: (dataTaskBlock) block {
  if (self.isUserAuthinticated) {
    NSString * urlString = [NSString stringWithFormat: @ "%@self/?access_token=%@", kUSERURL, [
      [NSUserDefaults standardUserDefaults] valueForKey: kAccessToken
    ]];
    [self makeRequestToServerWithUrl: urlString completionBlock: ^ (NSDictionary * data, NSError * error) {
      if (!error) {
        block(data, error);
      } else {
        block(nil, error);
      }
    }];
  } else {
    [self makeAuthenticateRequestWithBlock: ^ (BOOL success) {
      [self getinformationofOwnFollowsWithCompletionBlock: block];
    }];
    // block(nil,errorMsg);
  }
}

它将发送一个请求并使用返回的块构建webview。这一切都很好。但是,当我两次调用相同的方法时,我收到以下错误消息:

[self.instagramVC getInformationOfOwnWithCompletionBlock: ^ (NSDictionary * data, NSError * error) {
  NSLog(@ "%@", data);
}];
[self.instagramVC getInformationOfOwnWithCompletionBlock: ^ (NSDictionary * data, NSError * error) {
  NSLog(@ "DATA 2%@", data);
}];    

它返回最后一个被调用方法的块,输出将是DATA 2.我知道原因,这是因为self.block。所以请给我一个建议,以便我不必为每个请求使用全局块。

2 个答案:

答案 0 :(得分:1)

正如您所说,您的问题是您正在为所有请求使用全局块。您需要设置一个数据结构来保存有关每个待处理请求的信息。也许是一个可变的字典数组,其中每个字典包含该请求的请求和完成块。然后,当请求完成时,将请求与您的请求数组匹配,并执行相应的完成块。

答案 1 :(得分:0)

您可以将一个全局块用于不同的请求。使用本地范围创建此块,并且您的请求将获得自己的完成。