如何在Objective-C中获取未调用方法的返回值

时间:2011-06-14 17:23:46

标签: objective-c asihttprequest

我正在使用ASIHTTPRequest使用iOS应用程序中名为submitUserCredentials的方法执行异步URL请求。请求发送得很好,但问题是当从服务器返回响应时,ASIHTTPRequest被设置为另一个方法requestFinished接收并返回它。

当submitUserCredentials是我首先从视图控制器运行的方法时,如何获取requestFinished返回的服务器响应?

2 个答案:

答案 0 :(得分:2)

您将ViewController设置为符合ASIHTTPRequestDelegate协议:

@interface MyViewController : UIViewController <ASIHTTPRequestDelegate>

然后,实现

-(void) requestFinished(ASIHTTPRequest *)request;
ViewController实现中的

方法。现在,当请求完成时,将调用ViewController中的requestFinished:方法。如果您需要传递信息以及请求并使其在requestFinished:方法中可用,您可以将ASIHTTPRequest的userInfo属性设置为您喜欢的任何属性,并且它将在requestFinished中的request参数中可用:

对评论的回复:
如果您愿意阻止线程直到收到响应,则可以使用startSynchronous方法(来自ASI站点http://allseeing-i.com/ASIHTTPRequest/How-to-use的代码):

[request startSynchronous];
NSError *error = [request error];
if (!error) {
  NSString *response = [request responseString];
}

这样,您的submitUserCredentials方法会在服务器响应时等待,但它会返回服务器对该方法的响应。如果在等待响应时阻止您的UI将不适合您(并且可能不会),您可以启动新线程来运行submitUserCredentials方法,然后从那里调用startSynchronous:

[NSThread detachNewThreadSelector:@selector(submitUserCredentials:)
        toTarget:self withObject: credentials];

答案 1 :(得分:0)

您可以在这里提出几件不同的事情。我不知道它是哪一个。所以我会尝试回答所有这些问题。


您是否不知道何时调用requestFinished?您是否像这样设置了请求的委托?

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];

如果您这样做了,那么您应该为requestFinished:上面引用的任何内容实施self方法。


您不确定如何在requestFinished:中获取响应字符串吗?在这种情况下,解决方案很简单:

- (void)requestFinished:(ASIHTTPRequest *)request
{
   // Use when fetching text data
   NSString *responseString = [request responseString];

   // Use when fetching binary data
   NSData *responseData = [request responseData];
}

即。请求的responseStringresponseData会为您提供所需内容。


或者你是说你想以某种方式处理submitUserCredentials中的响应(也许是因为这个方法的局部变量有很多上下文)?如果是这样,那么最好的办法就是使用blocks

- (IBAction)grabURLInBackground:(id)sender
{
   NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
   __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
   [request setCompletionBlock:^{
      // Use when fetching text data
      NSString *responseString = [request responseString];

      // Use when fetching binary data
      NSData *responseData = [request responseData];
   }];
   [request setFailedBlock:^{
      NSError *error = [request error];
   }];
   [request startAsynchronous];
}

或许问题是您希望ASIHTTPRequest以同步方式工作?在这种情况下,您可以这样做:

- (IBAction)grabURL:(id)sender
{
  NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request startSynchronous];
  NSError *error = [request error];
  if (!error) {
    NSString *response = [request responseString];
  }
}

但不建议您这样做。这样做会挂起你的应用程序的主线程(假设你在主线程中进行调用)这不是一件好事。如果这确实是您正在寻找的答案,那么您可能需要阅读事件驱动编程。


注意:上面的所有代码示例都是从ASIHTTPRequest的优秀“How to use it”文档页面复制的。