在Obj-C中使用Swift协议的实现

时间:2016-04-14 17:18:38

标签: objective-c swift

我正在尝试使用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"

(将转换添加到赋值和/或方法调用没有帮助)

任何解决方案?

3 个答案:

答案 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的对象显然是AnyObjectid

答案 1 :(得分:-1)

您不使用@class来声明协议...而是必须导入包含协议定义的Swift兼容头。

同样要声明符合Obj C协议的对象,请使用id<TheProtocol>作为类型

答案 2 :(得分:-2)

解决了它,我只是将类型更改为id

id p = [[ObjCClass alloc] init];
[p someMethod];
相关问题