You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带Completion的Timer Selector函数调用出现EXC_BAD_ACCESS错误求助

Fixing EXC_BAD_ACCESS When Using Timer Selector with Completion Handler

Hey there, let's break down why you're hitting that EXC_BAD_ACCESS error and how to fix it.

The Root Cause

When you use #selector with a Timer, the system expects the target method to match one of two specific signatures:

  • A method with no parameters: @objc func methodName()
  • A method that accepts the triggering Timer as its only parameter: @objc func methodName(_ timer: Timer)

Your fetchDatabase(completion:) method has a closure parameter, which translates to an Objective-C block under the hood. When the Timer fires, it tries to call your method without passing that block parameter—this mismatch between what the method expects and what the Timer provides causes the memory access crash.

The Solution: Wrap the Call

The cleanest way to handle this is to create a dedicated "bridge" method that the Timer can call, and inside that method, invoke your fetchDatabase with the completion handler you want. Here's how:

  1. Add the wrapper method to your class:
@objc private func handleTimerFetch() {
    fetchDatabase { result in
        // Put your completion logic right here
        if result {
            print("Database fetch succeeded!")
        } else {
            print("Database fetch failed.")
        }
    }
}
  1. Update your Timer initialization to use this new selector:
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(handleTimerFetch), userInfo: nil, repeats: true)

Why This Works

  • The handleTimerFetch method matches the signature the Timer expects (no parameters), so the system can call it safely when the Timer fires.
  • Inside this wrapper, you get full control over calling fetchDatabase with your desired completion logic, avoiding the signature mismatch that caused the crash.

A Quick Note on Selector Signatures

If you ever need to access the Timer itself in your wrapper (e.g., to invalidate it early), you can adjust the wrapper to accept the Timer parameter:

@objc private func handleTimerFetch(_ timer: Timer) {
    fetchDatabase { result in
        // Your logic here
        if !result {
            timer.invalidate() // Stop the timer if fetch fails
        }
    }
}

Then update the Timer call to use this selector:

Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(handleTimerFetch(_:)), userInfo: nil, repeats: true)

内容的提问来源于stack exchange,提问作者Alex Wulff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:04:26