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

Swift协议中使用Objective-C Block遇属性未找到问题求助

解决Objective-C调用Swift协议Block属性的报错问题

这个问题其实是两个常见的跨语言桥接问题叠加导致的,我来帮你拆解并修复:

核心问题分析

  1. 类型识别问题:你在Objective-C里用NSObject *类型来访问callback属性,但编译器不知道这个NSObject实例实际上遵循了SwiftProtocol,自然找不到协议定义的属性。
  2. 可选性不匹配:原Objective-C协议里的callback是nullable的,但你定义的Swift协议里callback是非可选闭包,导致生成的OC头文件里属性是_Nonnull,不仅和原协议不一致,也可能导致OC侧赋值nil时出错。

具体修复步骤

1. 修正Swift协议的属性定义

把Swift协议里的callback改成可选闭包,并给属性加上@objc标注(确保编译器明确将其暴露给OC):

@objc public protocol SwiftProtocol: NSObjectProtocol {
    @objc var callback: (() -> Void)? { get set }
}

这样修改后,生成的Swift头文件里的属性会和原OC协议一致:

@property (nonatomic, copy, nullable) void (^callback)(void);

2. 在Objective-C中使用正确的类型

你需要把对象的类型声明或转换为id<SwiftProtocol>,而不是NSObject *,这样编译器才能识别协议的属性。比如:

// 错误写法:NSObject* 类型无法识别协议属性
// NSObject *obj = ...;
// obj.callback = ^{ /* ... */ };

// 正确写法1:直接声明为协议类型
id<SwiftProtocol> obj = yourInstance;
obj.callback = ^{
    // 你的回调逻辑
};

// 正确写法2:如果已有NSObject*变量,先强制转换
NSObject *obj = ...;
((id<SwiftProtocol>)obj).callback = ^{
    // 你的回调逻辑
};

额外注意点

  • 不需要使用@convention(block):在@objc协议中,Swift闭包会自动桥接为Objective-C block,手动指定反而可能引发不必要的类型问题。
  • 确保遵循协议的类也被@objc标注:如果你的Swift类遵循了SwiftProtocol,要给类加上@objc,这样OC才能识别这个类遵循了该协议。
  • Objective-C文件中正常导入Swift头文件即可:只要你的Swift代码正确暴露,Objective-C可以直接使用,不需要额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:00:24