我正在尝试使用Swift和Obj-C的混合实现一种中介类型的模式。我面临的问题是如何处理使用Obj-C的Swift协议实现类。看看代码,看看我的意思:
Swift协议及其实现:
@objc public protocol TheProtocol {
func someMethod()
}
@objc public class SwiftClass: NSObject, TheProtocol {
public func someMethod() {
print("someMethod Swift")
}
}
协议的ObjC实施:
#import "SwiftAndObjC-Swift.h"
@interface ObjCClass : NSObject <TheProtocol>
- (void) someMethod;
@end
@implementation ObjCClass
- (void) someMethod
{
NSLog(@"someMethod ObjC");
}
@end
我的问题是如何在ObjC中定义一些能够引用SwiftClass或ObjCClass的类型。例如,这不编译:
#import "SwiftAndObjC-Swift.h"
...
TheProtocol *p = [[ObjCClass alloc] init];
// Error: "Use of undeclared identifier TheProtocol"
这将编译:
@class TheProtocol
TheProtocol *p = [[ObjCClass alloc] init];
但不能使用p:
@class TheProtocol
TheProtocol *p = [[ObjCClass alloc] init];
[p someMethod];
// Error: Receiver type "The Protocol" is a forward declaration"
(将转换添加到赋值和/或方法调用没有帮助)
任何解决方案?
答案 0 :(得分:13)
在Objective-C中,协议不是一种类型。您应该声明符合协议的类:
id<TheProtocol> p = [[ObjCClass alloc] init];
编译前向声明的原因是因为前向声明的作用是什么 - 它们向编译器宣布一个类存在,并且链接器将在以后的构建过程中填充它。
(这也是改为id p =...
的原因。)
在Swift中,我们用类似的东西声明类:
class MyClass : Superclass, Protocol, AnotherProtocol { ... }
在Objective-C中我们使用:
@class MyClass : SuperClass <Protocol, AnotherProtocol>
// ...
@end
看到区别?在Swift中,协议和超类被混合到继承声明中,而Objective-C则以非常不同的方式处理它们。
协议和类在两种语言中的处理略有不同,因此使用方式不同。
ObjectiveC中的 id
类似于Swift中的AnyObject?
。在Objective-C中,符合SomeProtocol
的对象显然是AnyObject
或id
。
答案 1 :(得分:-1)
您不使用@class来声明协议...而是必须导入包含协议定义的Swift兼容头。
同样要声明符合Obj C协议的对象,请使用id<TheProtocol>
作为类型
答案 2 :(得分:-2)
解决了它,我只是将类型更改为id
id p = [[ObjCClass alloc] init];
[p someMethod];