在我的应用程序中,我需要调用一个getGroup()
函数,该函数使用用户信息联系我们的CMS,然后根据该信息和CMS中当前的内容将它们放在一个组中。该组信息包含在我们其他API调用的URL中。
问题在于,当应用程序启动且尚未缓存用户组时,每个API调用都会触发getGroup实际进行API调用,而不仅仅是获取缓存的组。我想减少它,以使调用仅进行一次,而对该函数的其他调用则等到听到响应为止。
我想做的伪代码示例:
var isGettingGroup = false
func getGroup(completion: (group?, error?)) {
if isGettingGroup {
wait for notification
}
if let group = groupFromCache() {
completion(group, nil)
} else {
isGettingGroup = true
callGetGroupAPI() { group, error in
completion(group, error)
cacheGroup(group)
isGettingGroup = false
send notification to continue
}
}
}
我尝试过使用信号灯,但是我认为我需要一些更全球化的东西,例如NotificationCenter
的帖子。我的主要问题是根据通知暂停单个函数调用,而不是等待分配的时间。我已经使用DispatchGroups
很多次了,但这似乎是相反的问题-多个函数在一个调用上等待,而不是函数/块在多个调用上等待。
预先感谢
答案 0 :(得分:1)
该调用仅进行一次,其他对该函数的调用将等待直到听到响应为止
该函数应在串行后台队列上同步运行其代码。这使得不可能由两个不同的线程同时调用它。这是您的伪代码的伪代码;未经测试,但显示出我认为可以使用的功能:
let q = DispatchQueue()
func getGroup(completion: (group?, error?)) {
q.sync { // lock out any other calls to getGroup until we finish
let g = DispatchGroup()
g.enter()
if let group = groupFromCache() {
completion(group, nil)
g.leave()
} else {
callGetGroupAPI() { group, error in
completion(group, error)
cacheGroup(group)
g.leave()
}
}
g.notify()
}
}
我不确定是否需要派遣小组,但我已将其放置在sync
范围内。
编辑:OP指出实际上是需要派遣组的,您需要说出g.wait()
而不是notify()
,但这是可行的。