Ios NSURL连接sendAsynchronousRequest如何保存响应?
我有以下方法:Ios NSURL连接sendAsynchronousRequest如何保存响应?,ios,objective-c,xcode,nsurlconnection,completionhandler,Ios,Objective C,Xcode,Nsurlconnection,Completionhandler,我有以下方法: .h @property (strong) NSString *reply; 现在,我尝试从块/处理程序返回一个值,但显然这是不可能的(或者我还没有弄清楚语法) 我试图设置一个局部变量来获取回复(数据)的值,但它会产生错误 不产生错误的唯一方法是使用类属性。但是当我试图读取[self reply]的值时,它是空的,这使我认为它从未设置过 我知道sendAsync函数是线程化和异步的,所以[self reply]的值是null,而当我使用sendSynchronousReques
.h
@property (strong) NSString *reply;
现在,我尝试从块/处理程序返回一个值,但显然这是不可能的(或者我还没有弄清楚语法)
我试图设置一个局部变量来获取回复(数据)的值,但它会产生错误
不产生错误的唯一方法是使用类属性。但是当我试图读取[self reply]的值时,它是空的,这使我认为它从未设置过
我知道sendAsync函数是线程化和异步的,所以[self reply]的值是null,而当我使用sendSynchronousRequest时,我总是得到一个回复
我做错了什么,如何从completionHandler中返回值
编辑1:我觉得我做错了什么。我在跟踪代码,当我使用同步发送时,一切正常。使用异步调用时,从未执行对sendAsynchronousRequest的实际调用,这使我认为线程没有被调用,因此该值为空
编辑#2:我找到了一种解决方法,添加了以下内容:
.m
@synthesize reply;
- (void)send
{
[NSURLConnection sendAsynchronousRequest:[self request]
queue:[[NSOperationQueue alloc] init]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error)
{
//NSLog(@"Error,%@", [error localizedDescription]);
[self setReply: [[NSString alloc] initWithString:[error localizedDescription]]];
}
else
{
//NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
[self setReply: [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
}
}];
}
然而,我不能完全确定我是否理解它是如何工作的。我假设RunLoop告诉异步操作运行2秒(我可以验证,因为当将日期间隔设置为较低的值时,由于使用实时服务器进行测试,我会得到一个空响应)。我不明白的是,当我只是告诉RunLoop运行时,它会永远阻止一切,就像当前线程从未终止一样。您应该尝试使用u block关键字声明您的属性回复
[NSURLConnection sendAsynchronousRequest:[self request]
queue:[NSOperationQueue alloc] init
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error)
{
//NSLog(@"Error,%@", [error localizedDescription]);
[self setReply: [[NSString alloc] initWithString:[error localizedDescription]]];
}
else
{
//NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
[self setReply: [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
}
}];
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 2]];
此关键字使您的属性可从块内部写入
编辑
关于在收到响应或请求超时之前阻止主线程的方法的建议:
@property (strong) __block NSString *reply;
您应该尝试使用_block关键字来声明您的属性回复
[NSURLConnection sendAsynchronousRequest:[self request]
queue:[NSOperationQueue alloc] init
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error)
{
//NSLog(@"Error,%@", [error localizedDescription]);
[self setReply: [[NSString alloc] initWithString:[error localizedDescription]]];
}
else
{
//NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
[self setReply: [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
}
}];
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 2]];
此关键字使您的属性可从块内部写入
编辑
关于在收到响应或请求超时之前阻止主线程的方法的建议:
@property (strong) __block NSString *reply;
摆脱该runUntilDate并尝试使用[NSOperationQueue mainQueue],看看这是否会改变什么
[self waitUntilBlockTrue:^{
//returns YES as long as the method should block
return (BOOL)(self.reply == nil);
} orTimeout:10];
摆脱该runUntilDate并尝试使用[NSOperationQueue mainQueue],看看这是否会改变什么
[self waitUntilBlockTrue:^{
//returns YES as long as the method should block
return (BOOL)(self.reply == nil);
} orTimeout:10];
差不多一个月后,我找到了解决问题的办法:
[NSURLConnection sendAsynchronousRequest:[self request]
queue:[NSOperationQueue mainQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error)...
这对我起了作用。请记住,我必须正确实现NSConnection的委托方法(didReceiveResponse、didReceiveData、didFailWithError、ConnectiondFinishLoading)。
但是,它现在是异步工作的,不会冻结UI,并且有正确的错误报告。
希望它能帮助那些陷入同样问题的人差不多一个月后,我找到了解决问题的方法:
[NSURLConnection sendAsynchronousRequest:[self request]
queue:[NSOperationQueue mainQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error)...
这对我起了作用。请记住,我必须正确实现NSConnection的委托方法(didReceiveResponse、didReceiveData、didFailWithError、ConnectiondFinishLoading)。
但是,它现在是异步工作的,不会冻结UI,并且有正确的错误报告。
希望它能帮助那些陷入同样问题的人我不理解这个问题。为什么不能从块完成函数返回一个值?setReply函数的作用是什么?向我们显示代码集断点,以查看数据是否有效或为空。您所处的轨道是正确的,这似乎是有效的,但您可能无法获取可以使用的信息。该块被指定为具有void返回类型,因此该块本身无法返回值-但为什么需要返回值?我猜你的setReply函数只是一个实例变量的setter?在这种情况下,您不需要从块中返回任何内容,因为在setReply时将捕获响应。使用局部变量捕获数据值时会产生什么错误?您应该能够设置一个断点来查看数据。此外,我还将添加检查您收到的响应代码。我基本上希望从asyncRequest返回一个值(一个字符串)。我已经试着搜索了几个小时如何从嵌套函数返回一个值,但没有结果。问题是“reply”从未设置,并且由于某种原因保持为空。NSLog确实打印出值/响应,但是当我尝试设置本地属性时,它没有设置。我不理解问题/问题。为什么不能从块完成函数返回一个值?setReply函数的作用是什么?向我们显示代码集断点,以查看数据是否有效或为空。您所处的轨道是正确的,这似乎是有效的,但您可能无法获取可以使用的信息。该块被指定为具有void返回类型,因此该块本身无法返回值-但为什么需要返回值?我猜你的setReply函数只是一个实例变量的setter?在这种情况下,您不需要从块中返回任何内容,因为在setReply时将捕获响应。使用局部变量捕获数据值时会产生什么错误?您应该能够设置一个断点来查看数据。此外,我还将添加检查您收到的响应代码。我基本上希望从asyncRequest返回一个值(一个字符串)。我已经试着搜索了几个小时如何从嵌套函数返回一个值,但没有结果。问题是“reply”从未设置,并且由于某种原因保持为空。NSLog确实打印出值/响应,但是当我尝试设置本地属性时,它没有设置。我尝试过,没有产生任何影响。事实上,这是我第一次尝试的方式。我已经尝试过了,没有什么不同。事实上,这是我第一次尝试的方式。尝试了,没有什么不同。我猜主要的线索是