gpt4 book ai didi

ios - 当 dispatch_group_wait() 由于超时返回时在 iOS 8 上崩溃

转载 作者:行者123 更新时间:2023-11-28 06:48:34 29 4
gpt4 key购买 nike

我有两个获取值的操作。我只关心两个值的总和。如果花费的时间太长,我根本不关心值(value)。

所以我认为使用组对 GCD 来说是一件容易的事。不幸的是,下面的代码只能在 iOS 9 上正常工作。每次我没有匹配的 dispatch_group_enter()/dispatch_group_leave() 调用时,我都会崩溃。

文档明确指出我必须匹配这两个调用。但是当我在 dispatch_group_wait() 上使用超时时,不可能有与 enter 调用相同数量的 leave 调用;这就是指定超时的全部要点。

那么这是 iOS 8 中的一个已知错误吗?难道我做错了什么?对于我最初遇到的问题,还有其他适用于 iOS 8 的解决方案吗?

编辑:实际上我们可以将其归结为:

var sync_group: dispatch_group_t = dispatch_group_create();
dispatch_group_enter(sync_group);
let maxWait = dispatch_time(DISPATCH_TIME_NOW, Int64(60 * NSEC_PER_SEC))
let result = dispatch_group_wait(sync_group, maxWait)

sync_group = dispatch_group_create();

在 iOS 9 上按预期工作,但在最后一行的 iOS 8 上确实崩溃,因为无法释放旧的 dispatch_group_t 实例。有任何简单的解决方法吗?

编辑 2:原来它在 iOS 9.0 上也坏了。它只能在 iOS 9.1+ 中正常工作。


原始代码:

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {

/* We want this method to block until the network code succeeded. */
let sync_group: dispatch_group_t = dispatch_group_create();

/* Start async operation 1. */
dispatch_group_enter(sync_group);
self.someAsyncOperation1({(value: Int, finalValue: Bool) in
if (finalValue) {
valOp1 = value
dispatch_group_leave(sync_group);
}
})

/* Start async operation 2. */
dispatch_group_enter(sync_group);
self.someAsyncOperation2({(value: Int, finalValue: Bool) in
if (finalValue) {
valOp2 = value
dispatch_group_leave(sync_group)
}
})

/* Block current thread until all leaves were called. If it takes more then 60 sec we don't care and let go. */
let maxWait = dispatch_time(DISPATCH_TIME_NOW, Int64(60 * NSEC_PER_SEC))
let result = dispatch_group_wait(sync_group, maxWait)
if (result > 0) {
/* This will result in a crash when we leave the scope: SIGTRAP in dispatch_semaphore_dispose */
return
}

dispatch_async(dispatch_get_main_queue(), {
let newValue = valOp1 + valOp2
self.lastKnownNotificationCombinedCounter = newValue
success(newValue)
})
})

实际的崩溃循环是这样的:

Exception Type:  SIGTRAP
Exception Codes: #0 at 0x3958a2a4

Thread 2 Crashed:
0 libdispatch.dylib 0x3958a2a4 _dispatch_semaphore_dispose$VARIANT$mp + 48
1 libdispatch.dylib 0x3958b491 _dispatch_dispose$VARIANT$mp + 30
2 libdispatch.dylib 0x3957ea8f -[OS_dispatch_object _xref_dispose] + 44
3 myApp 0x00176a24 block_destroy_helper67 + 354
4 myApp 0x00176ab8 0x2e000 + 1346232
5 myApp 0x00178334 0x2e000 + 1352500
6 libsystem_blocks.dylib 0x395d3adb _Block_release + 216
7 Foundation 0x2c4143b9 -[NSBlockOperation dealloc] + 58
8 libobjc.A.dylib 0x39036d57 objc_object::sidetable_release(bool) + 164
9 libobjc.A.dylib 0x390371a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 402
10 libdispatch.dylib 0x39589423 _dispatch_root_queue_drain + 1176
11 libdispatch.dylib 0x3958a1fb _dispatch_worker_thread3 + 104
12 libsystem_pthread.dylib 0x396fae25 _pthread_wqthread + 666
13 libsystem_pthread.dylib 0x396fab78 start_wqthread + 6

最佳答案

我想到了这个解决方法:

private let MAX_TRIES = 20;

func dispatch_group_wait_ios8Safe(group: dispatch_group_t, _ timeout: dispatch_time_t) -> Int {

if #available(iOS 9, *) {
/* Just forward the call. */
return dispatch_group_wait(group, timeout)
} else {
/* Forward the call to original function and store result. */
let firstResult = dispatch_group_wait(group, timeout)
var result = firstResult, tries = 0
while(result > 0 && tries < MAX_TRIES) {
dispatch_group_leave(group)
result = dispatch_group_wait(group, DISPATCH_TIME_NOW)
tries += 1
}

/* Return original result. */
return firstResult
}
}

因此,在有人提出更好的解决方案之前,我会坚持这一点。

关于ios - 当 dispatch_group_wait() 由于超时返回时在 iOS 8 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35554866/

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