Group Group Group Group Group Group Group Group Group

Testing Timers causes crash on a UITableView

Hi, I’m having some problems when trying to test a Timer because causes a table view that I have in my app to crash. I’ve tried moving the code that is going to be executed to a background thread but from time to time happens again. Could you tell me some strategies to solve this problem?

 public final class DefaultTimer: TimerProtocol {
    private(set) weak var timer: Timer?

    public init() { }

    public func schedule(timeInterval: TimeInterval, repeats: Bool, completionBlock: @escaping CompletionBlock) {
        self.timer?.invalidate()
        let timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: repeats) {
            (timer) -> Void in
            DispatchQueue.global(qos: .background).async {
                completionBlock()
            }
        }
        self.timer = timer
    }

    public func invalidate() {
        timer?.invalidate()
        timer = nil
    }

    public func fire() {
        timer?.fire()
    }

    deinit {
        invalidate()
    }
 }

These are basically the tests I’m using:

func testInit_internalTimerIsNilWhenInstantiated() {
        var times = 0
        let exp = expectation(description: "timer")
        XCTAssertNil(sut.timer)
        sut.schedule(timeInterval: 1, repeats: false, completionBlock: {
            times += 1
            exp.fulfill()
        })
        sut.fire()
        wait(for: [exp], timeout: 1)
        XCTAssertNotNil(sut.timer)
        XCTAssertEqual(times, 1)
        sut.invalidate()
        XCTAssertNil(sut.timer)
    }
    
    func testSchedule_schedulesOperationAsAndReapeatsItAsRequired() {
        var times = 0
        let expectedTimes = 2
        let exp = expectation(description: "timer")
        let closure: DefaultTimer.CompletionBlock = {
            times += 1
            times == expectedTimes ? exp.fulfill() : ()
        }
        sut.schedule(timeInterval: 0.3, repeats: true, completionBlock: closure)
        wait(for: [exp], timeout: 1)
        XCTAssertEqual(times, expectedTimes)
    }

@armdevp Do you still have issues with this?