Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSURL连接sendAsynchronousRequest如何保存响应?_Ios_Objective C_Xcode_Nsurlconnection_Completionhandler - Fatal编程技术网

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确实打印出值/响应,但是当我尝试设置本地属性时,它没有设置。我尝试过,没有产生任何影响。事实上,这是我第一次尝试的方式。我已经尝试过了,没有什么不同。事实上,这是我第一次尝试的方式。尝试了,没有什么不同。我猜主要的线索是