我确实向网络服务发出请求并得到响应。我将响应转换为 NSMutableArray。我在 NSURLSessionDataTask 中的响应,现在我想返回 NSMutableArray 以便在 NSURLSessionDataTask 之外使用。这是我的代码:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"url"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSString *postString = @"params";
NSString *postLength = [NSString stringWithFormat:@"%lu", ( unsigned long )[postString length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length" ];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *task = [[self getURLSession] dataTaskWithRequest:request completionHandler:^( NSData *data, NSURLResponse *response, NSError *error )
{
dispatch_async( dispatch_get_main_queue(),
^{
NSDictionary *dicData = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:nil];
NSDictionary *values = [dicData valueForKeyPath:@"smth"];
NSArray * dataArr = [dicData objectForKey:@"smth"];
NSArray * closeArr = [values objectForKey:@"0"];
NSUInteger dataCount = [dataArr count] ;
NSUInteger closeCount = [closeArr count] ;
NSMutableArray * newData = [NSMutableArray new] ; //<-- THIS ARRAY
for(int i = 0 ; i<dataCount && i<closeCount ; i++)
{
NSMutableDictionary * temp = [NSMutableDictionary new] ;
NSString * dataString = [dataArr objectAtIndex:i];
NSString * closeString = [closeArr objectAtIndex:i];
[temp setObject:dataString forKey:@"smth"];
[temp setObject:closeString forKey:@"smth"];
[newData addObject:temp];
}
NSLog(@"%@", newData);
} );
}];
[task resume];
我需要返回 NSMutableArray * newData = [NSMutableArray new];
长话短说,我从 Web 服务获取 json 数据,然后将其转换为适当的 json 格式以在图表中显示(我使用 shinobicontrols)。现在,我在本地 json 的帮助下显示图表。这是代码:
_timeSeries = [NSMutableArray new];
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"AppleStockPrices" ofType:@"json"];
NSData* json = [NSData dataWithContentsOfFile:filePath];
NSArray* data = [NSJSONSerialization JSONObjectWithData:json
options:NSJSONReadingAllowFragments
error:nil];
for (NSDictionary* jsonPoint in data) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"smth1"]
andValue:jsonPoint[@"smth2"]];
[_timeSeries addObject:datapoint];
}
当我试图在 NSURLSessionDataTask 中实现这段代码时,图表没有出现。所以我需要在外面返回 NSMutableArray(我的数据在适当的 json 格式中)。
我该怎么做?有任何想法吗? 谢谢!
最佳答案
您不能在完成处理程序中添加 return 语句,因为如果 session 返回错误,则可能不会调用它。事实上,如果您尝试这样做,Xcode 会给您一个“不兼容的指针类型”错误。
我发现绕过它的最佳方法是将 newData 数组设置为属性,并使其可供类中的其他方法使用。如果在 url session 任务结束时特定方法需要处理此数组,您可以从完成处理程序调用该方法或使用通知。
或者,如果出于某种原因您不想使用类属性,您可以使用 NSNotificationCenter,并将 newData 传递给通知对象中的监听器。
编辑使用属性的代码示例
如果您需要完成 block 之外的 newData,一种简单的方法是将数组声明为属性。这不是唯一的方法,也可能不是最好的。但它并没有给代码增加太多的复杂性。 您可以在 .m 类文件中声明 newData 数组:
@interface "whatever class you are using"
@property (nonatomic, strong) NSMutableArray *newData;
@end
您可以在 viewDidLoad 方法中初始化数组:
- (void)viewDidLoad {
_newdata = [[NSMutableArray alloc] init];
}
在您的完成 block 中,您将删除初始化并将数据添加到数组。
//NSMutableArray * newData = [NSMutableArray new] ; // REMOVE THE INTIALIZATION
for(int i = 0 ; i<dataCount && i<closeCount ; i++) {
NSMutableDictionary * temp = [NSMutableDictionary new] ;
NSString * dataString = [dataArr objectAtIndex:i];
NSString * closeString = [closeArr objectAtIndex:i];
[temp setObject:dataString forKey:@"smth"];
[temp setObject:closeString forKey:@"smth"];
[_newData addObject:temp];
}
同样,这不是最好的方法,但它相对简单。这样做的一个问题是,由于您对数组有强引用,如果您需要执行另一个 URL 调用并将新数据加载到数组中,则需要清空它。否则,新数据将附加到旧数据。您可以在再次调用 URL session 之前调用 [_newData removeAllObjects]; 来完成此操作。
编辑 2:根据用户评论更改代码:
- (void)loadChartData {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"url"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSString *postString = @"params";
NSString *postLength = [NSString stringWithFormat:@"%lu", ( unsigned long )[postString length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length" ];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *task = [[self getURLSession] dataTaskWithRequest:request completionHandler:^( NSData *data, NSURLResponse *response, NSError *error ) {
dispatch_async( dispatch_get_main_queue(), ^{
NSDictionary *dicData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSDictionary *values = [dicData valueForKeyPath:@"smth"];
NSArray * dataArr = [dicData objectForKey:@"smth"];
NSArray * closeArr = [values objectForKey:@"smth0"];
NSUInteger dataCount = [dataArr count] ;
NSUInteger closeCount = [closeArr count] ;
NSMutableArray * newData = [NSMutableArray new] ;
for(int i = 0 ; i<dataCount && i<closeCount ; i++) {
NSMutableDictionary * temp = [NSMutableDictionary new] ;
NSString * dataString = [dataArr objectAtIndex:i];
NSString * closeString = [closeArr objectAtIndex:i];
[temp setObject:dataString forKey:@"smth"];
[temp setObject:closeString forKey:@"smth"];
[newData addObject:temp];
}
NSLog(@"%@", newData);
_timeSeries = [NSMutableArray new];
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"AppleStockPrices" ofType:@"json"];
NSData* json = [NSData dataWithContentsOfFile:filePath];
NSArray* data = [NSJSONSerialization JSONObjectWithData:json options:NSJSONReadingAllowFragments error:nil];
for (NSDictionary* jsonPoint in data) {
SChartDataPoint* datapoint = [self dataPointForDate:jsonPoint[@"smth"] andValue:jsonPoint[@"smth"]];
[_timeSeries addObject:datapoint];
}
});
}];
[task resume];
// Code here has a good chance of being executed before the completion block is complete
// _newdata = [[NSMutableArray alloc] init];
// NSLog(@"%@", _newdata);
}
关于ios - 从 completionHandler 返回 NSMutableArray( Objective-C ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40693271/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998
在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我一直在研究RubyKoans,我发现about_open_classes.rbkoan很有趣。特别是他们修改Integer#even?方法的最后一个测试。我想尝试一下这个概念,所以我打开了Irb并尝试运行Integer.respond_to?(:even?),但令我惊讶的是我得到了错误。然后我尝试了Fixnum.respond_to?(:even?)并得到了错误。我还尝试了Integer.respond_to?(:respond_to?)并得到了true,当我执行2.even?时,我也得到了true。我不知道发生了什么。谁能告诉我缺少什么? 最佳答案
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U