将 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 协议,规则似乎都是相同的。
我已经阅读了 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 协议,规则似乎都是相同的。