Ios 实现时间敏感调度队列的最佳方法
所以我有一个服务,我可以通过在请求主体中传递profileID来请求用户的profilejson。如果我需要10个人资料,我会传入10个profileID,服务器会返回所有10个个人资料信息。最大计数=20 因此,我添加了一个优化算法,根据用户快速滚动或用户在应用程序中打开一堆配置文件等对一堆profileid进行分组。。。基本上,我的逻辑是,我有一个调度队列,等待大约0.6秒,在这段时间内,我有一个数组,收集应用程序中不同视图要求的所有ProfileID。0.6秒后,无论数组中排队的是什么,我都将其包含在请求正文中,并将其发送到服务器 我可以在这里使用更好的策略/设计模式吗? 我的实现如下所示Ios 实现时间敏感调度队列的最佳方法,ios,objective-c,multithreading,optimization,queue,Ios,Objective C,Multithreading,Optimization,Queue,所以我有一个服务,我可以通过在请求主体中传递profileID来请求用户的profilejson。如果我需要10个人资料,我会传入10个profileID,服务器会返回所有10个个人资料信息。最大计数=20 因此,我添加了一个优化算法,根据用户快速滚动或用户在应用程序中打开一堆配置文件等对一堆profileid进行分组。。。基本上,我的逻辑是,我有一个调度队列,等待大约0.6秒,在这段时间内,我有一个数组,收集应用程序中不同视图要求的所有ProfileID。0.6秒后,无论数组中排队的是什么,我
----> call in the main thread <--------
CXAssert([NSThread isMainThread], @"profileInfoForUsers should be main thread");
if (!profileIDCacheWaitingToRequest) {
profileIDCacheWaitingToRequest = [NSMutableArray array];
}
if (!profileIDArraySubmittedToTheServer) {
profileIDArraySubmittedToTheServer = [NSMutableArray array];
}
if (!_profile_batch_process_queue) {
_profile_batch_process_queue = dispatch_queue_create("com.gather.chatx.profile.batch.process", DISPATCH_QUEUE_SERIAL);
}
NSMutableArray *filteredProfileIDCache = [NSMutableArray array];
for (NSString *profileID in users) {
if (profileID == NULL) {
continue;
}
if (![profileIDArraySubmittedToTheServer containsObject:profileID]) {
CXDebugLog(@"Not sent to server yet");
if (![profileIDCacheWaitingToRequest containsObject:profileID]) {
CXDebugLog(@"Not added to queue yet yet");
[filteredProfileIDCache addObject:[profileID copy]];
} else {
CXDebugLog(@"Already present in the queue, will fire soon");
}
} else {
CXDebugLog(@"Skipping profile download call for %@", profileID);
}
}
if (filteredProfileIDCache.count == 0) {
CXDebugLog(@"No need for submitting profile to server as we are already waiting on server to return..");
completion (nil, nil);
return;
}
for (NSString *pid in filteredProfileIDCache) {
if (profileIDCacheWaitingToRequest.count <= GROUP_PROFILE_MAX_COUNT) {
[profileIDCacheWaitingToRequest addObject:pid];
} else {
CXDebugLog(@"wait next turn. hope the user makes this call.");
continue;
}
}
CXProdLog(@"Queuing profiles for download...");
dispatch_async(_profile_batch_process_queue, ^{
// this block will keep executing once its a serial queue..
/////// SLEEP this thread, and wait for 0.6 seconds
sleep(0.6);
dispatch_async(dispatch_get_main_queue(), ^{
if (profileIDCacheWaitingToRequest.count == 0) {
completion (nil, nil);
return ;
}
NSArray *profileIDsToRequest = [profileIDCacheWaitingToRequest copy];
[profileIDArraySubmittedToTheServer addObjectsFromArray:profileIDsToRequest];
CXProdLog(@"Fetching profiles from server with count %lu", (unsigned long)profileIDsToRequest.count);
if (profileIDsToRequest.count > GROUP_PROFILE_MAX_COUNT) {
CXDebugLog(@"We are exceeding the count here");
NSMutableArray *array = [NSMutableArray arrayWithArray:profileIDsToRequest];
NSUInteger totalNumberOfObjectsToRemove = profileIDsToRequest.count - GROUP_PROFILE_MAX_COUNT;
for (int i = 0; i < totalNumberOfObjectsToRemove; i ++) {
[array removeLastObject];
}
profileIDsToRequest = array;
}
[CXDownloader downloadProfileForUsers:profileIDsToRequest sessionKey:self.sessionKey completion:^(NSDictionary *profileData, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[profileIDArraySubmittedToTheServer removeAllObjects];
if (profileData) {
....
}
else {
....
}
});
}];
[profileIDCacheWaitingToRequest removeAllObjects];
});
});
--->在主线程中调用我无法获得打开后台线程,然后睡眠,然后返回主线程的逻辑?为什么不把所有代码都放在后台线程中,让主线程部分保持原样呢。毕竟,您的代码将在后台线程中同步运行……我不能将所有内容都放在后台线程中。当线程休眠0.6秒时,我仍然需要一些东西来处理所有传入的请求以获取ProfileIds如果您将所有代码(除了主线程gcd)放入,它不应该阻止您处理传入的请求。。。传入的请求来自哪里?这里的关键是睡眠(0.6)代码。该线程将休眠以填充数组,然后对其进行处理。传入的请求可以来自任何地方/任何层。在这里,所有内容都被编译。代码的第一部分将在后台线程中睡眠开始之前在主线程上同步完成。因此,代码中的0.6秒只会延迟代码的第二部分。它没有让任何时间来完成…我不能得到背后的逻辑打开一个背景线程,然后睡觉,然后回到主线程?为什么不把所有代码都放在后台线程中,让主线程部分保持原样呢。毕竟,您的代码将在后台线程中同步运行……我不能将所有内容都放在后台线程中。当线程休眠0.6秒时,我仍然需要一些东西来处理所有传入的请求以获取ProfileIds如果您将所有代码(除了主线程gcd)放入,它不应该阻止您处理传入的请求。。。传入的请求来自哪里?这里的关键是睡眠(0.6)代码。该线程将休眠以填充数组,然后对其进行处理。传入的请求可以来自任何地方/任何层。在这里,所有内容都被编译。代码的第一部分将在后台线程中睡眠开始之前在主线程上同步完成。因此,代码中的0.6秒只会延迟代码的第二部分。它不让任何事情有时间完成。。。