所以每当我加载ViewController时,我都会上传到服务器。然而,似乎存在问题。当存在大量异步请求时,它可以使应用程序半崩溃。我的意思是请求只是不会通过,没有其他请求(在另一个线程上)继续。最重要的是,键盘变得极其迟钝(我知道很奇怪)。无论如何,考虑到其他网络请求因此而无法发送,这是一个严重的问题。我觉得奇怪的是,上传请求的数量与下载请求的数量相同(上传甚至不做任何事情,他们只是发出正常的http请求),但下载请求可以正常工作。这是我的代码:
- (void)serverUploadAll:(myEntity *)send
{
NSMutableString *urlString = [[NSMutableString alloc] initWithString:ServerApiURL];
NSString *addTargetUrl = [NSString stringWithFormat:@"/addtarget?deviceToken=%@&appVersion=%@&targetId=%@", postToServer.deviceToken, postToServer.appVersion, send.Id];
[urlString appendString:addTargetUrl];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:queueTwo completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
//NSLog(@"response=%@", response);
//NSLog(@"data=%@", data);
//NSLog(@"error=%@", error);
}];
}
上述代码在数据库循环时被调用,当存在大量呼叫时,即120+,就会出现问题。我的下载请求实际上是使用AFNetworking完成的,所以也许这就是他们高效工作的原因。无论如何,总而言之,为什么当多次调用上面的代码时它只是堵塞,并停止?
感谢您的帮助,非常感谢。
问候,
麦克
更新:所以,多亏了runmad的精彩回答,我正在使用AFNetworking方法,但是,它崩溃了这个错误-[AFHTTPRequestOperation _propertyForKey:]: unrecognized selector sent to instance
。我不知道为什么这不起作用,这是我的代码:
- (void)cycleThroughEntries
{
MyEntity *myEntity;
NSMutableArray *urlRequests;
urlRequests = [[NSMutableArray alloc] init];
for (id i in fetchedResultsController.fetchedObjects) {
myEntity = i;
NSMutableString *urlString = [[NSMutableString alloc] initWithString:ServerApiURL];
NSString *addTargetUrl = [NSString stringWithFormat:@"/addtarget?deviceToken=%@&appVersion=%@&targetId=%@", postToServer.deviceToken, postToServer.appVersion, myEntity.Id];
[urlString appendString:addTargetUrl];
//NSLog(@"URL sent is: %@", urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[urlRequests addObject:requestOperation];
}
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@""]];
[client enqueueBatchOfHTTPRequestOperationsWithRequests:urlRequests
progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
NSLog(@"%d / %d", numberOfCompletedOperations, totalNumberOfOperations);
}
completionBlock:^(NSArray *operations) {
NSLog(@"All Done!");
}];
}
不完全确定什么是错的,所以会很感激帮助。感谢。
更新2:已修复。我不应该制作一个AFHTTPRequestOperations
的数组,而是正常NSURLRequests
。问题解决了!!
答案 0 :(得分:4)
您可以进行多少个异步连接是有限制的 - 即使它们出现在后台线程上也是如此。同时120多个网络电话听起来有点疯狂,特别是如果它们包含的上传时间超过了GET请求。
我建议您考虑重写您需要请求/上传到服务器的内容以减少请求数量。您需要确保呼叫不会同时发生,并且在其他呼叫完成之前您会暂停呼叫。
输入NSOperationQueue
...
我会创建一个处理所有请求的经理类。在此课程中,您可以创建NSOperationQueue
,以便继续向其添加请求。 Here's a good tutorial。您可以设置并发请求的数量,NSOperationQueue将确保队列中的下一个请求等待,直到当前正在运行的请求完成。通过网络为您带来了很多繁重的工作。
您还可以考虑查看AFNetworking的NSOperationQueues
来排队所有网络电话,这样它们就不会同时发生。
在AFNetworking的AFHTTPClient
中,您可以使用以下方法,具体取决于您设置请求的方式:
- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)urlRequests
progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
completionBlock:(void (^)(NSArray *operations))completionBlock;
那应该让你开始:)祝你好运。
<强>更新强>
如果需要,您还可以向AFNetworking operationsQueue添加操作。如果它当前没有运行,你必须确保启动它。这样,您就可以在不同时间从应用的其他部分添加其他请求。您始终可以检查是否有任何操作正在/正在运行队列中,而且令人敬畏的是,您可以轻松取消任何正在运行的操作。它可以找到here。