Ios 处理多个NSURL连接的最佳方法
我正在尝试以编程方式创建xls工作表。为了填写表格,我将多重Ios 处理多个NSURL连接的最佳方法,ios,objective-c,nsurlconnection,sendasynchronousrequest,Ios,Objective C,Nsurlconnection,Sendasynchronousrequest,我正在尝试以编程方式创建xls工作表。为了填写表格,我将多重NSURLConnection设置为100左右。现在,我的方法是: 建立连接并将数据存储到数组中。这个数组有100个对象 现在获取第一个对象并调用连接。存储数据。并与数组中的第二个对象进行第二次连接。这将一直持续到数组中的最后一个对象 完成100个连接平均需要14秒。有没有办法实现NSURLConnection以更快的方式获得响应 直到昨天,我一直遵循以下基本方法: 声明属性: @property (nonatomic,strong)
NSURLConnection
设置为100左右。现在,我的方法是:
NSURLConnection
以更快的方式获得响应
直到昨天,我一直遵循以下基本方法:
声明属性:
@property (nonatomic,strong) NSURLConnection *getReportConnection;
@property (retain, nonatomic) NSMutableData *receivedData;
@property (nonatomic,strong) NSMutableArray *reportArray;
在viewDidLoad
中初始化数组:
reportArray=[[NSMutableArray alloc]init];
在按钮操作中初始化NSURLConnection:
/initialize url that is going to be fetched.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"****/%@/crash_reasons",ID]];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:tokenReceived forHTTPHeaderField:@"**Token"];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//initialize a connection from request
self.getReportConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
处理接收到的数据:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{
if (connection==_getVersionConnection) {
[self.receivedData_ver appendData:data];
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];
[JSON[@"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (![obj[@"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[@"id"]]) {
[reportArray_ver addObject:obj[@"id"]];
}
NSLog(@"index = %lu, Object For title Key = %@", (unsigned long)idx, obj[@"id"]);
}];
if (JSON!=nil) {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Version Reports succesfully retrieved" message:@"" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alert show];
}
}
}
在一个连接完成后调用另一个连接:
// This method is used to process the data after connection has made successfully.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connection==getReportConnection) {
//check and call the connection again
}
}
今天,我尝试了NSURLConnection
和sendascync
使用loop一个接一个地启动所有连接,效果非常好
self.receivedData_ver=[[NSMutableData alloc]init];
__block NSInteger outstandingRequests = [reqArray count];
for (NSString *URL in reqArray) {
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
[self.receivedData appendData:data]; //What is the use of appending NSdata into Nsmutable data?
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];
NSLog(@"login json is %@",JSON);
[JSON[@"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (![obj[@"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[@"id"]]) {
[reportArray_ver addObject:obj[@"id"]];
}
NSLog(@"index = %lu, Object For title Key = %@", (unsigned long)idx, obj[@"id"]);
}];
outstandingRequests--;
if (outstandingRequests == 0) {
//all req are finished
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Version Reports succesfully retrieved" message:@"" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alert show];
}
}];
}
这一次完成100个请求所用的时间是旧过程的一半,除了asynReq之外还有没有其他更快的方法?使用
NSURLconnection
和NSURLconnection with asyncReq
的最佳方案是什么?使用sendAsynchronous
是改进代码组织的一个很好的方法。我相信,经过仔细的审查,我们可以在边际上提高速度,但显著提高速度的方法是不要提出100个请求
如果响应体很小,则创建一个端点来响应结果的连接
如果响应主体很大,那么您请求的数据就超过了用户目前的需要。仅在用户需要查看的内容上打开UI,然后以静默方式获取其余内容(…或者,可能比静默方式更好,以懒散方式)
如果你不控制服务器,而且响应主体很小,用户需要全部或大部分响应才能继续使用应用程序,那么你可以开始在应用程序运行时提高性能和UI技巧,以取悦用户,但通常这些约束中的一个——通常是后者——可以放松。一些观察结果:
NSURLSession
而不是NSURLConnection
(如果您支持iOS 7.0及更高版本):
sendAsynchronousRequest
实现(或mydataTaskWithRequest
)一样同时发出请求,而不是按顺序发出。这就是获得巨大性能优势的原因
但是请注意,您不能保证它们完全按照您发布它们的顺序运行,因此您需要使用一些支持这一点的结构(例如,使用NSMutableDictionary
或使用占位符预先填充NSMutableArray
,这样您就可以简单地更新特定索引处的条目,而不是向数组中添加项)
总之,请注意,它们可能不会按照要求的顺序完成,因此请确保您适当地处理它们dispatch_group_t group = dispatch_group_create();
for (NSString *URL in URLArray) {
dispatch_group_enter(group);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
// configure the request here
// now issue the request
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// check error and/or handle response here
// when all done, leave group
dispatch_group_leave(group);
}];
[task resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// do whatever you want when all of the requests are done
});
didReceiveData
中解析数据。这应该只是将数据附加到NSMutableData
。在connectiondFinishLoading
委托方法中进行所有解析
如果您使用基于块的实现,这个问题就会消失,但这只是对代码片段的观察为什么不使用NSURLSession?NSURLConnection现在已被弃用。在建立连接时,我只是显示进度条,并在连接完成后将其删除。@Rob-我尝试将url会话放入循环中,但没有执行。不知何故,url会话中的代码块被跳过。@T_77-好的,然后进行一些基本的诊断带有日志语句或断点的nostics,确保您按您应该的方式点击
恢复
行。但是使用NSURLSession
的这种模式非常标准,因此我怀疑问题与此无关。请求是否正确启动?请尝试使用来观察请求。@Rob它起作用了。我也可以投票支持您的答案,但是对不起,我没有足够的代表!!!谢谢gr8的回答。我错过了dispatcg小组notify@Rob脱帽致敬真的很有用
dispatch_group_t group = dispatch_group_create();
for (NSString *URL in URLArray) {
dispatch_group_enter(group);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
// configure the request here
// now issue the request
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// check error and/or handle response here
// when all done, leave group
dispatch_group_leave(group);
}];
[task resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// do whatever you want when all of the requests are done
});