将 Swift 协议一致性添加到 Objective-C header 并使其成为 public

Add Swift protocol conformance to Objective-C header and make it public

我已经阅读了 here and here 关于在 Objective-C header 中遵守 Swift 协议的内容,但我不太了解我想要的行为 - 我我也在寻求更好地了解这一切是如何运作的。这是我的场景。

我在 Swift 中有一个协议:

PersonalDetailsProtocol.swift

@objc
protocol PersonalDetailsProtocol {
    func doSomeWork()
}

然后我有一个 Objective-C class 和一个 header 和实现文件

RegistrationPersonalDetails.h

@protocol PersonalDetailsProtocol; // Forward declare my Swift protocol

@interface RegistrationPersonalDetails : NSObject <PersonalDetailsProtocol>

@end

RegistrationPersonalDetails.m

#import "RegistrationPersonalDetails.h"

@implementation RegistrationPersonalDetails

- (void)doSomeWork {
    NSLog(@"Working...");
}
@end

此时一切都可以编译,尽管 RegistrationPersonalDetails.h 文件中有一条警告指出 Cannot find protocol definition for 'PersonalDetailsProtocol'。除了那个警告,我面临的问题是我不能 publicly 在 RegistrationPersonalDetails.

的实例上调用 doSomeWork 方法

Swift 中的调用站点类似于:

let personalDetails = RegistrationPersonalDetails()
personalDetails.doSomeWork()

但我收到一条错误消息:

Value of type 'RegistrationPersonalDetails' has no member 'doSomeWork'

我知道该方法不是 public,因为它没有在 header 文件中声明。但我不认为只要协议符合 public 即在 header 文件中声明。

任何人都可以在这里指出正确的道路并提供解释吗?或者这甚至可能吗?我显然可以在 ObjC 中重写协议,但我总是尝试添加新代码 Swift.

在纯 objective-c 中,如果不将 class 导入 header,则无法使它符合协议。要使用私有协议,不应在 header 中声明一致性。但是,仍然可以使用强制转换来调用这样的方法,但是应该谨慎进行,因为它有点不安全:

if ([anInstance respondToSelector:@selector(myProtocolMethod)])
    [(id<MyProtocol>)anInstance myProtocolMethod];

我不熟悉 Swift,但我认为你可以用这种方式(或类似的方式)做同样的事情:

 if let conformingInstance = anInstance as? MyProtocol
     conformingInstance.myProtocolMethod

编辑:为了完成我的第一个断言,当您需要声明接收或返回符合该协议的实例的方法时,仍然可以在 header 中使用前向声明:

@SomeProtocol;

// This is not possible
@interface MyClass : NSObject <SomeProtocol>         

// But this is possible
@property (nonatomic) id<SomeProtocol> someProperty;
-(void) someMethod:(id<SomeProtocol>)object; 
@end

在此document苹果公司明确表示:

Forward declarations of Swift classes and protocols can be used only as types for method and property declarations.

因此无论协议是 Objective-c 协议还是 Swift 协议,规则似乎都是相同的。