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

SwiftUI中如何实现Objective-C库的Delegate/Protocol方法?

在SwiftUI中实现Objective-C代理协议的解决方案

问题核心原因

  1. 值类型无法适配OC代理系统:SwiftUI视图是struct(值类型),而Objective-C的代理机制仅支持引用类型(NSObject子类)——OC的id指向的是类实例,值类型无法被OC的消息传递系统识别。
  2. OC代码本身的Selector错误:原OC库中检查的@selector(endEvent: done:)与协议定义的endEvent:不匹配,这是逻辑错误,即使UIKit场景下能偶然工作,也会导致SwiftUI场景下直接失败。
  3. Swift方法签名不匹配:你在SwiftUI视图中写的endEvent(sender: Myclass , endEvent done:Bool),和OC协议要求的endEvent(_ done: Bool)签名完全不符。

修复步骤

步骤1:修正OC库的Selector错误(优先处理)

如果有权限修改OC库,把notifyEndEvent中的Selector检查改为正确的协议方法签名:

-(void)notifyEndEvent
{
    if (myDelegate == nil)
        return;

    // 修正:协议方法是endEvent:,不是endEvent: done:
    if ([myDelegate respondsToSelector:@selector(endEvent:)]) {
        [myDelegate endEvent:done];
    } else {
        printf("endEvent not implemented by the caller\n"); 
    }
}

步骤2:创建代理中转类(适配OC与SwiftUI)

由于SwiftUI视图是值类型,需要创建一个NSObject子类作为代理中转,承接OC的代理事件后,通过闭包传递给SwiftUI视图:

// 代理中转类,遵循OC的CustomDelegate协议
class CustomDelegateHandler: NSObject, CustomDelegate {
    // 闭包用于将OC事件传递给SwiftUI视图
    var onEndEvent: ((Bool) -> Void)?
    
    // 实现OC协议要求的方法
    func endEvent(_ done: Bool) {
        onEndEvent?(done)
    }
}

步骤3:在SwiftUI视图中使用中转类

struct ContentView: View {
    // 用@StateObject保持代理类实例的生命周期稳定
    @StateObject private var delegateHandler = CustomDelegateHandler()
    @State private var myclass = Myclass()

    var body: some View {
        Button("Start") {
            start()
        }
        .onAppear {
            // 绑定事件回调
            delegateHandler.onEndEvent = { done in
                print("endEvent \(done)")
                // 在这里处理SwiftUI侧的UI更新逻辑
            }
        }
    }

    private func start() {
        // 将中转类实例设置为OC对象的代理
        myclass.setDelegate(delegateHandler)
    }
}

关键说明

  • @StateObject用于保证代理中转类的实例在SwiftUI视图刷新时不会被重新创建,确保OC侧能持续找到正确的代理对象。
  • 中转类作为NSObject子类,完全符合OC对代理对象的类型要求,能被OC的respondsToSelector正确识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:00:43