尝试实现一个应用程序,该应用程序在连接到Internet时将存储在本地数据库中的脱机数据发送到Web服务器。我使用下面显示的代码。到目前为止,我测试它工作正常,不确定它将适用于大量的记录。我想知道是否对此代码进行任何调整可能会提高性能???
注意
从app到服务器的单向同步。
-(void)FormatAnswersInJSON {
DMInternetReachability *checkInternet = [[DMInternetReachability alloc] init];
if ([checkInternet isInternetReachable]) {
if ([checkInternet isHostReachable:@"www.apple.com"]) {//Change to domain
responseArray = [[NSMutableArray alloc] init];
dispatch_async(backgroundQueue, ^(void) {
NSArray *auditIDArray = [[NSArray alloc] initWithArray: [self getUnuploadedIDs]];
for (int temp = 0; temp < [auditIDArray count]; temp ++) {
// Code to post JSON to server
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!error) {
NSString *responseID = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
if ([responseID isEqualToString:@"ERROR"]) {
//Error uploading records
} else {
[responseArray addObject:responseID];
}
} else {
//Error
return;
}
}
dispatch_async( backgroundQueue, ^{
/* Based on return code update local DB */
for (int temp = 0; temp < [responseArray count]; temp ++) {
[self updateRecordsForID:[auditIDArray objectAtIndex:temp] withID:[responseArray objectAtIndex:temp]];
}
});
});
}
}
}
- (void)upload { //Called when internet connection available
if(backgroundQueue){
dispatch_suspend(backgroundQueue);
dispatch_release(backgroundQueue);
backgroundQueue = nil;
}
backgroundQueue = dispatch_queue_create("com.XXXX.TestApp.bgqueue", NULL);
dispatch_async(backgroundQueue, ^(void) {
[self FormatAnswersInJSON];
});
}
答案 0 :(得分:1)
如果这段代码放在我面前,我的方法是:
我的优化途径是进行群组处理。粗略的算法类似于:
for records in groups of X
collect
post to server {
on return:
gather records that updated successfully
update locally
}
这假设您可以修改服务器代码。你可以做10,20,50等组,所有这些都取决于发送的数据类型和大小。
组算法意味着更多的预处理客户端,但具有减少HTTP请求的能力。如果您只获得少量更新,则YAGNI和预成熟优化。
请勿让此决定阻止您发货!
答案 1 :(得分:0)
您的代码有几个问题。一种惯例是在测试error参数之前始终检查返回值。可能会设置error参数 - 即使方法成功。
将NSURLConnection
用于快速示例或测试以外的任何其他内容时,您还应始终使用异步样式来处理委托方法。由于正确使用NSURLConnection
可能会变得很麻烦且容易出错,我建议使用第三方框架封装NSURLConnection
对象和所有连接相关的状态信息作为子类NSOperation
。您可以在Apple示例中找到一个示例实现:QHTTPOperation
。另一个合适的第三方框架是AFNetworking(在GitHub上)。
当您使用带有委托或第三方子类的异步样式时,您可以取消连接,检索详细错误或进度信息,执行身份验证等等 - 使用同步API无法实现这一点。
我认为,一旦你完成了这个并且你的方法正常工作,你可以测试性能是否可以接受。但除非你有大量数据 - 比如&gt; 2 MByte - 我不会太担心。
如果您的数据变得非常大,请说> 10 MByte,您需要考虑改进您的方法。例如,您可以将POST数据作为文件流而不是NSData
对象提供(请参阅NSURLRequest
的属性HTTPBodyStream
)。使用流可以避免将所有POST数据加载到RAM中,这有助于缓解有限的RAM问题。
如果你有较小的POST数据,但可能有很多,你可以考虑使用NSOperationQueue
放置NSOperation
连接子类。将最大并发操作数设置为2.然后可以利用HTTP流水线 - 如果服务器支持此操作,这实际上可以减少延迟。
当然,您的应用中可能还有其他部分,例如您创建或检索必须发送的数据,这可能会影响整体性能。但是,如果你的代码是健全的,并且利用调度队列或NSOperations让事情在并行中执行,那么提供连接性能的选择就不多了。