Xcode提示:Instance will be immediately deallocated because property ‘delegate’ is ‘weak’
Xcode提示:Instance will be immediately deallocated because property ‘delegate’ is ‘weak’

Xcode提示:Instance will be immediately deallocated because property ‘delegate’ is ‘weak’

问题描述

在Xcode中使用WCSession时:

struct pigletApp: App {
    init() {
        if WCSession.isSupported() {
            print("当前设备支持 WCSession 。")
            WCSession.default.delegate = WCSessionDelegateImpl() // 报错行
            WCSession.default.activate()
        }
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class WCSessionDelegateImpl: NSObject, WCSessionDelegate { }

Xcode提示:

Instance will be immediately deallocated because property 'delegate' is 'weak'
Weak reference will always be nil because the referenced object is deallocated here

这个错误提示是因为 WCSession.default.delegate 是一个 弱引用(weak),它会在对象不再需要时自动释放。因此,当 WCSessionDelegateImpl 直接赋值给 delegate 时,WCSessionDelegateImpl 对象会被立即释放,导致委托(delegate)为 nil,从而无法正常工作。

解决方案

要解决这个问题,需要将 WCSessionDelegateImpl 的实例存储在一个强引用(strong)的地方,确保它在使用期间不会被释放。可以将 WCSessionDelegateImpl 保存在 @StateObject 或 @ObservedObject 中,或者将它作为一个实例变量进行持有。

struct pigletApp: App {

    // 使用 @StateObject 或 @ObservedObject 来保持对 WCSessionDelegateImpl 实例的强引用
    @StateObject private var wcSessionDelegate = WCSessionDelegateImpl()

    init() {
        if WCSession.isSupported() {
            print("当前设备支持 WCSession 。")
            WCSession.default.delegate = wcSessionDelegate // 报错行
            WCSession.default.activate()
        }
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class WCSessionDelegateImpl: NSObject, WCSessionDelegate { }

@StateObject:确保 wcSessionDelegate 在应用生命周期内保持强引用,避免在 WCSession 激活时被释放。这样,WCSession.default.delegate 始终引用一个有效的对象。

使用 @StateObject 或其他持有方式(如实例变量)来确保 WCSessionDelegateImpl 不会被系统自动释放是关键。这样,当 WCSession 激活时,委托对象才能继续有效。

总结

WCSessionDelegate 的委托对象应该持有强引用。使用 @StateObject 来初始化并持有它,可以确保对象在应用生命周期内不会被提前销毁。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注