我必须提高连接到Parse的iOS应用的性能。到目前为止,我已经检查过一些findObject查询需要太长时间,有些甚至是10秒!
我会把最坏情况之一的代码和迄今为止我尝试过的代码放在一起:
+ (void) getAllEvents
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PFQuery *timestampsQuery = [PFQuery queryWithClassName:@"TimeStamp"];
[timestampsQuery fromLocalDatastore];
[timestampsQuery whereKey:@"type" equalTo:@"event"];
// This query very often (not always) takes a couple of seconds
NSArray *timeStampObjects = [timestampsQuery findObjects];
NSArray *timeStamps = [self TransformPFObjectIntoTimeStamp:timeStampObjects];
PFQuery *query = [PFQuery queryWithClassName:@"Event"];
if ([self noNetworkConnection])
{
[query fromLocalDatastore];
}
else
{
[query whereKey:@"user" equalTo:[PFUser currentUser]];
}
[query includeKey:@"admin"];
// This query very often (not always) takes several seconds, 6, 7…even 10 seconds!
NSArray *objects = [query findObjects];
NSMutableArray *eventArray = [NSMutableArray arrayWithArray:[self TransformPFObjectIntoEvents:objects]];
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:eventArray,@"events",timeStamps,@"timestamps", nil];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:GET_ALL_MY_EVENTS object:dict];
});
});
}
+ (NSArray *)TransformPFObjectIntoTimeStamp:(NSArray *)objects
{
NSMutableArray* timestamps = [[NSMutableArray alloc]init];
for (PFObject* object in objects)
{
TimeStamp* timeStamp = [[TimeStamp alloc] init];
timeStamp.parseObject = object;
[timestamps addObject:timeStamp];
}
return timestamps;
}
+ (NSMutableArray *)TransformPFObjectIntoEvents:(NSArray *)objects
{
[PFObject pinAllInBackground:objects withName:PFObjectDefaultPin];
NSMutableArray* eventArray = [[NSMutableArray alloc]init];
for (PFObject* object in objects)
{
Event* event = [[Event alloc] init];
event.parseObject = object;
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObject:object[@"channel"] forKey:@"channels"];
[currentInstallation saveInBackground];
if(event.parseObject[@"imageFile"] != [NSNull null])
{
PFFile *userImageFile = event.parseObject[@"imageFile"];
if (userImageFile != NULL)
{
UIImage *image = [UIImage imageWithData:[userImageFile getData]];
[event setAttributeImage:image];
}
}
[eventArray addObject:event];
}
return eventArray;
}
我必须补充说,对findObjects的第二次调用有时会给我一个“cfnetwork sslhandshake failed(-9824)”,这对我来说很奇怪,因为应用程序的info.plist包含这些键(但我想这应该是另一个问题):
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
另外,表“事件”有超过1000个寄存器。
我尝试了什么:
1)注释[timestampsQuery fromLocalDatastore]; 相同的结果,这些查询需要太长时间。
2)用户findObjectInBackground:
+ (void) getAllMyEvents{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
_calls = 0;
PFQuery *timestampsQuery = [PFQuery queryWithClassName:@"TimeStamp"];
[timestampsQuery fromLocalDatastore];
[timestampsQuery whereKey:@"type" equalTo:@"event"];
[timestampsQuery findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
[self completeQueriesWithType:1 andObjects:objects];
}];
PFQuery *query = [PFQuery queryWithClassName:@"Event"];
if ([self noNetworkConnection])
{
[query fromLocalDatastore];
}
else
{
[query whereKey:@"user" equalTo:[PFUser currentUser]];
}
[query includeKey:@"admin"];
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
[self completeQueriesWithType:2 andObjects:objects];
}] ;
});
}
+ (void) completeQueriesWithType:(int)type andObjects:(NSArray *)objs
{
_calls++;
NSArray *timeStamps = nil;
NSMutableArray *eventArray = nil;
if(type == 1)
{
timeStamps = [TimeStamp TransformPFObjectIntoTimeStamp:objs];
}
else if(type == 2)
{
eventArray = [NSMutableArray arrayWithArray:[self TransformPFObjectIntoEvents:objs]];
}
if(_calls == 2)
{
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:eventArray,@"events",timeStamps,@"timestamps", nil];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:GET_ALL_MY_EVENTS object:dict];
});
}
}
但它仍然需要几秒钟而且我也遇到了这个错误:“警告:正在主线程上执行长时间运行的操作。 打破warnBlockingOperationOnMainThread()进行调试。“为什么?如果我在后台运行它。
因为我知道Parse本地数据库对性能有一些影响我虽然根本没有使用它,但是删除它的所有外观,但我想用Parse本地数据库修复它,如果可能的话。
那么......为什么这些查询花了这么多时间?
修改 按照@Wain的建议,我已经完成了这个测试:
+ (void) getAllEvents
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Running only second of findObjects");
PFQuery *query = [PFQuery queryWithClassName:@"Event"];
if ([self noNetworkConnection])
{
NSLog(@"Reading from local datastore");
[query fromLocalDatastore];
}
else
{
[query whereKey:@"user" equalTo:[PFUser currentUser]];
}
[query includeKey:@"admin"];
// This query very often (not always) takes several seconds, 6, 7…even 10 seconds!
NSLog(@"Just before findObjects");
NSArray *objects = [query findObjects];
NSLog(@"End of running only second of findObjects");
});
}
有了这些结果:
2016-03-31 11:15:29.295 MyApp[...] Running only second of findObjects
2016-03-31 11:15:29.318 MyApp[...] Just before findObjects
2016-03-31 11:15:38.025 MyApp[...] End of running only second of findObjects
只有这个方法NSArray * objects = [query findObjects];需要9秒!
编辑2 我不确定这是否重要,但是&#34;事件中的一个字段&#34; table是PFFile(图像)。这会使查询查询变慢吗?
答案 0 :(得分:0)
您可以更改许多内容,但是您应该使用工具来查看实际花费最多时间的内容。需要考虑的事项:
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
&amp;循环中的[currentInstallation saveInBackground];
UIImage *image = [UIImage imageWithData:[userImageFile getData]];
您正在将初始下载视为罪魁祸首,但更有可能是您的后续处理,您将开始大量的安装保存和同步图像下载......