由于超时而返回dispatch_group_wait()时,iOS 8崩溃

斯克维茨

我有两个获取值的操作。我只关心两个值的总和。如果花费太长时间,我根本不会在乎它的价值。

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

文档明确指出,我必须同时匹配这两个调用。但是,当我在on上使用超时时dispatch_group_wait(),就不可能有与Enter呼叫相同数量的请假呼叫。这就是指定超时的重点。

那么这是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
    }
}

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ios8 _updateInterfaceOrientationFromDeviceOrientation崩溃

来自分类Dev

iOS 8上的神秘崩溃

来自分类Dev

iOS8 NSXMLParser崩溃

来自分类Dev

iOS8的KeychainItemWrapper崩溃

来自分类Dev

GPUImage在iOS 8中崩溃

来自分类Dev

iOS 8上的UIWebView崩溃

来自分类Dev

UICollectionView节标题崩溃,导致iOS 8崩溃

来自分类Dev

在iOS 8设备上查找崩溃日志

来自分类Dev

iOS8 +苹果的KeychainItemWrapper导致崩溃

来自分类Dev

iOS8 Swift:deleteRowsAtIndexPaths崩溃

来自分类Dev

关于addObserver的ios8崩溃:

来自分类Dev

UICollectionView节头崩溃iOS 8

来自分类Dev

iOS8中的自动布局崩溃

来自分类Dev

iOS 8上的UI框架崩溃

来自分类Dev

Restkit由于json问题而在iOS 8中崩溃?

来自分类Dev

转换为使用iOS 8 Popover Segues时,UISplitViewController崩溃

来自分类Dev

调用UIActivityViewController时,iOS 8 iPad应用程序崩溃

来自分类Dev

Datepicker在iOS 8文本字段上崩溃

来自分类Dev

ASIHTTPRequest使ios8上的应用程序崩溃

来自分类Dev

IPConfiguration apple80211Open()在iOS8上崩溃

来自分类Dev

iOS8出现KeychainItemWrapper崩溃

来自分类Dev

Swift UIAlertController-> ActionSheet iPad iOS8崩溃

来自分类Dev

iOS8中的UISearchBar自定义InputView崩溃

来自分类Dev

iOS8中的VFR阅读器崩溃

来自分类Dev

iOS8 / iPhone6 + XPC崩溃

来自分类Dev

iOS8的SpriteKit中EXC_BAD_ACESS崩溃

来自分类Dev

应用仅在特定设备ios8中崩溃

来自分类Dev

Java 8的最新更新,现在+ PrintAssembly在14.10时崩溃

来自分类Dev

在performBlock中重置我的NSManagedObjectContext时,iOS 8应用程序崩溃