访问swift数组时swift_isUniquelyReferenced_nonNull_native中的EXC_BAD_ACCESS

问题描述 投票:2回答:1

问题

[编写单元测试并嘲笑我看到的NSTimer时,>]

Exception: EXC_BAD_ACCESS (code=1, address=0x8)

内部

swift_isUniquelyReferenced_nonNull_native

在此处访问数组invalidateInvocations(在func invalidate()内部)时,会出现这种情况。

class TimerMock: Timer {

    /// Timer callback type
    typealias TimerCallback = ((Timer) -> Void)

    /// The latest used timer mock accessible to control
    static var  currentTimer: TimerMock!

    /// The block to be invoked on a firing
    private var block:        TimerCallback!

    /// Invalidation invocations (will contain the fireInvocation indices)
    var invalidateInvocations: [Int] = []

    /// Fire invocation count
    var fireInvocations:       Int   = 0

    /// Main function to control a timer fire
    override open func fire() {
        block(self)
        fireInvocations += 1
    }

    /// Hook into invalidation
    override open func invalidate() {
        invalidateInvocations.append(fireInvocations)
    }

    /// Hook into the timer configuration
    override open class func scheduledTimer(withTimeInterval interval: TimeInterval,
                                            repeats: Bool,
                                            block: @escaping TimerCallback) -> Timer {
        // return timer mock
        TimerMock.currentTimer = TimerMock()
        TimerMock.currentTimer.block = block
        return TimerMock.currentTimer
    }

}

有趣的是,如果我将invalidateInvocations更改为常规Int,则可以对其进行访问而不会发生任何崩溃。

因为访问此变量会导致EXC_BAD_ACCESS,所以我认为该数组已经被释放,但是我看不到如何发生。

演示

您可以在此存储库中看到一个完整的正在运行且崩溃的示例(分支demo/crash

https://github.com/nomad5modules/ArcProgressViewIOS/tree/demo/crash

只需执行单元测试,然后查看它就会崩溃。

问题

这里发生了什么?我也已经在其他项目中观察到swift_isUniquelyReferenced_nonNull_native内部发生崩溃的情况,我希望完全理解此失败的原因!那么,如何找出问题所在?以及如何解决?

独立复制项目

https://drive.google.com/file/d/1fMGhgpmBRG6hzpaiTM9lO_zCZwNhwIpx/view?usp=sharing

问题,在编写单元测试并嘲笑NSTimer时,我看到一个异常:swift_isUniquelyReferenced_nonNull_native内部的EXC_BAD_ACCESS(代码= 1,地址= 0x8)这种情况...

ios swift xcode memory-management exc-bad-access
1个回答
0
投票

崩溃是由于未初始化成员(这是NSObject而不是常规的swift类,因此需要显式的init(),但由于这是Timer,它具有半抽象指定的初始化器,因此不允许重写)。

© www.soinside.com 2019 - 2024. All rights reserved.