Objective-C类别中的Swift协议

时间:2016-06-16 00:37:23

标签: objective-c swift swift-protocols

我在Swift中定义了一个协议:

@objc public protocol UploadProtocol: class {
    func isUploaded() -> Bool
    ...
}

我在我的ProjectName-Swift.h文件(旧项目)中导入我的ProjectName_Prefix.pch文件。

在Objective-C中,我在一个实现协议的类上有一个类别。我试图弄清楚如何让编译器了解该实现。这就是我一直在做的事情:

// Person+Upload.h
#import "Person.h"

@interface Person (Upload)
- (BOOL)isUploaded;
@end


// Person+Upload.m
#import "Person+Upload.h"
@implementation Person (Upload)
...
@end

这给了我:

  

无法找到' UploadProtocol'

的协议定义

我只能想到其他三种方法来设置它,所有这些方法都有问题。我错过了什么?

First Way(Apple推荐)

在使用Swift与Cocoa和Objective-C(Swift 2.2)时,Apple说," Objective-C类可以通过导入Xcode生成的头文件,在其实现(.m)文件中采用Swift协议。 Swift代码并使用类扩展。"但他们的例子是标准类。如果我尝试使用我的类别执行此操作:

// Person+Upload.h
#import "Person.h"

@interface Person (Upload)
- (BOOL)isUploaded;
@end


// Person+Upload.m
#import "Person+Upload.h"

@interface Person (Upload) <UploadProtocol>
@end

@implementation Person (Upload)
...
@end

这导致:

  

类别的重复定义&#39;上传&#39;在界面&#39; Person&#39;

第二种方式

好的,所以我想避免两次定义上传课程。因此,我会将其从.h删除。

// Person+Upload.h
#import "Person.h"

@interface Person ()
- (BOOL)isUploaded;
@end


// Person+Upload.m
#import "Person+Upload.h"

@interface Person (Upload) <UploadProtocol>
@end

@implementation Person (Upload)
...
@end

在这种情况下,我得到:

  

类别正在实施一种方法,该方法也将由其主要类

实施

我目前正在声明.h中的方法,以便其他类可以调用其中一些方法,而无需转换为协议来访问该方法。

第三种方式

如果我将类别名称保留在.h中,请在.m

中将其删除
// Person+Upload.h
#import "Person.h"

@interface Person (Upload)
- (BOOL)isUploaded;
@end


// Person+Upload.m
#import "Person+Upload.h"

@interface Person () <UploadProtocol>
@end

@implementation Person (Upload)
...
@end

然后我得到:

  

类别正在实施一种方法,该方法也将由其主要类

实施

每次都是将它投入协议的唯一解决方案吗?在多个地方添加这种类型的行看起来像代码味道:

Person <Upload> *s = (Person <Upload> *)self;

还有其他解决方案吗?

1 个答案:

答案 0 :(得分:1)

感谢有趣的问题!

您的初始方法实际上会增加协议的前向声明:

// Person+Upload.h
#import "Person.h"

@protocol UploadProtocol; // NOTE THIS!!!

@interface Person (Upload) <UploadProtocol>
//- (BOOL)isUploaded;  // This is not really needed
@end


// Person+Upload.m
#import "Person+Upload.h"
#import "...-Swift.h"  // IMPORTANT!!!
@implementation Person (Upload)
// HERE you implement isUploaded, of course.
...
@end

这仍会导致编译器警告Cannot find protocol definition for 'UploadProtocol',但它应该有效。

Apple推荐的方式也有效,Duplicate definition of category只是一个警告,但Person不会被Swift代码识别为符合协议,即使它符合要求Objective-C认可。最初的方法也适用于Swift。