gpt4 book ai didi

ios - 如何同时处理三个请求正确创建并发队列

转载 作者:行者123 更新时间:2023-11-28 18:31:08 24 4
gpt4 key购买 nike

我想同时获取三个请求来提高性能。这是我当前的代码,它只在我的表格 View 中返回一个平台:

 dispatch_queue_t concurrentQueue = dispatch_queue_create("com.myapp.myqueue", DISPATCH_QUEUE_CONCURRENT);

void(^block_readPS4)() = ^{
self.releasesDict = [NSDictionary dictionaryWithDictionary:[self getDataWithPlatform:@"ps4"]];
};
void(^block_readXONE)() = ^{
self.releasesDict = [NSDictionary dictionaryWithDictionary:[self getDataWithPlatform:@"xboxone"]];
};
void(^block_readPC)() = ^{
self.releasesDict = [NSDictionary dictionaryWithDictionary:[self getDataWithPlatform:@"pc"]];
};
void(^block_write)() = ^{dictionaryWithDictionary:self.releasesDict];
self.releasesArr = [self.releasesDict allKeys];
[self.tableView reloadData];
[self.activityInd stopAnimating];
};
dispatch_async(concurrentQueue,block_readPS4);
dispatch_async(concurrentQueue,block_readXONE);
dispatch_async(concurrentQueue,block_readPC);

dispatch_barrier_async(concurrentQueue, block_write);

我知道问题出在 self.releasesDict 中,如何改进?

最佳答案

@ryancrunchi 是正确的:

You're overwriting self.releasesDict in each read. So in your write block the value of self.releasesDict will be the last read that the system performed.

...但是他提出的解决方案并不能保护字典免受并发写入,而且 NSMutableDictionary 本质上不是线程安全的。您必须保护它免受并发读取+写入和/或写入+写入。这是您可以执行此操作的一种方法(在评论中详细介绍了所做的一切):

// A local (non-shared) mutable dictionary. Using a local dictionary allows us to know that no one
// else is reading from or writing to it concurrently, which is not guaranteed if we use self.releasesDict
NSMutableDictionary* localDict = [NSMutableDictionary dictionary];

// Your original concurrent queue
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.myapp.myqueue", DISPATCH_QUEUE_CONCURRENT);

// A serial queue to protect localDict from reading and writing.
dispatch_queue_t localDictWriteQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);

// Make this queue target the concurrent queue. Not strictly required, but you had everything executing on
// concurrentQueue before, and this preserves that, while also protecting localDict.
dispatch_set_target_queue(localDictWriteQueue, concurrentQueue);

// A dispatch group that allows us to perform an operation only after all the constituent writes have finished.
dispatch_group_t group = dispatch_group_create();

// For each platform, enter the group, then fire off the concurrent block
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
// Fetch into a dictionary that is local to the block.
NSDictionary* x = [self getDataWithPlatform:@"ps4"];

// Then, on the serial localDictWriteQueue merge those entries into the shared local dictionary
dispatch_async(localDictWriteQueue, ^{
[localDict addEntriesFromDictionary: x];
// This balances out the dispatch_group_enter operation we did right before we enqueued this
dispatch_group_leave(group);
});
});

// Second verse, same as the first
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSDictionary* x = [self getDataWithPlatform:@"xboxone"];
dispatch_async(localDictWriteQueue, ^{
[localDict addEntriesFromDictionary: x];
dispatch_group_leave(group);
});
});

// Third verse, same as the first
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSDictionary* x = [self getDataWithPlatform:@"pc"];
dispatch_async(localDictWriteQueue, ^{
[localDict addEntriesFromDictionary: x];
dispatch_group_leave(group);
});
});

// Then set up the block we want to run at the end... use main queue because it updates UI.
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// Update self.releasesDict all at once, on the main thread
// Note: we do not need to do this read of localDict on localDictWriteQueue because if this block is executing, we know (semantically) that all possible
// write operations have already completed, and that no other writes to localDict are possible because it's local to this method call.
self.releasesDict = localDict;
// Same idea
self.releasesArr = [self.releasesDict allKeys];

// Update UI based on state changes to self.
[self.tableView reloadData];
[self.activityInd stopAnimating];
});

关于ios - 如何同时处理三个请求正确创建并发队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29821545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com