Ios 实现时间敏感调度队列的最佳方法

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秒后,无论数组中排队的是什么,我

所以我有一个服务,我可以通过在请求主体中传递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秒只会延迟代码的第二部分。它不让任何事情有时间完成。。。