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

watchOS后台任务调用setTaskCompleted时崩溃问题求助

Troubleshooting Watch Extension Crash on setTaskCompleted with WCSession KVO

Let’s walk through the likely causes of this crash and how to fix them, since your setup involves WCSession KVO in the ExtensionDelegate’s init method.

Common Causes & Fixes

1. Missing KVO Observer Cleanup

When you add KVO observers in init, you must remove them before the ExtensionDelegate instance is deallocated. Watch Extensions have a tight lifecycle—if the extension is suspended or terminated and the observers aren’t removed, subsequent WCSession state changes will send notifications to a deallocated object, which almost always causes a crash (especially when interacting with background tasks).

Add a deinit method to your ExtensionDelegate to clean up the observers:

deinit {
    guard WCSession.isSupported() else { return }
    let session = WCSession.default
    // Match the exact key paths and context used when adding observers
    session.removeObserver(self, forKeyPath: "activationState", context: &ExtensionDelegate.wcSessionKVOcontext)
    session.removeObserver(self, forKeyPath: "hasContentPending", context: &ExtensionDelegate.wcSessionKVOcontext)
}

Important: Never use nil for the context parameter when removing observers—this can accidentally remove observers added by parent classes or other parts of your code, leading to unexpected behavior.

2. Timing Conflicts Between WCSession KVO and Background Tasks

WCSession state changes (like activationState or hasContentPending) might fire after you’ve marked a background task as completed. If your KVO callback attempts to interact with the already-completed task (or the extension is in a deallocation state), this can trigger a crash.

Fix this by:

  • Ensuring you remove KVO observers before calling setTaskCompleted(). For example, if your background task handles WCSession content, clean up observers once the content is processed and before marking the task as done.
  • Adding a guard clause in your KVO callback to check if the background task is still active before performing any operations.

3. Duplicate Calls to setTaskCompleted

If your KVO callbacks accidentally trigger multiple calls to setTaskCompleted() for the same background task, this will cause a crash. WatchKit strictly enforces that each background task is completed exactly once.

Prevent this by:

  • Using a private boolean property to track whether the task has already been completed:
    private var isTaskCompleted = false
    
    func completeBackgroundTask(_ task: WKBackgroundTask) {
        guard !isTaskCompleted else { return }
        isTaskCompleted = true
        task.setTaskCompleted()
    }
    
  • Checking the task’s state (if possible) before calling setTaskCompleted().

4. Accidental Deallocation of ExtensionDelegate

If your ExtensionDelegate instance is deallocated prematurely (e.g., due to incorrect memory management), the KVO notifications will target a dangling pointer. To confirm this, add a print statement in deinit to see if it’s being called before you expect:

deinit {
    print("ExtensionDelegate deallocated")
    // ... observer cleanup code
}

If you see this print before your background task completes, you’ll need to adjust your memory management to keep the delegate alive until the task is done.

  • Prefer WCSession Delegates Over KVO: Watch Connectivity provides delegate methods like session(_:activationDidCompleteWith:error:), sessionDidBecomeInactive(_:), and sessionHasContentPending(_:) that are designed to handle state changes without the risk of KVO memory leaks. This is a more robust approach than KVO for Watch Extensions.
  • Delay KVO Setup: Instead of adding observers in init, wait until the extension finishes launching (e.g., in applicationDidFinishLaunching). This ensures the session is properly initialized before observing it.
  • Tighten Background Task Scope: Keep background task logic focused—process the required content, clean up resources (like KVO observers), and mark the task as completed as soon as possible.

内容的提问来源于stack exchange,提问作者Reinhard Männer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:49:43