转换为Swift 3重命名了我自己的Objective-C方法

时间:2016-10-20 14:21:55

标签: objective-c swift swift3

我使用Objective-C代码混合了swift类。使用Swift 2.3,一切都很好并按预期工作。

我最近转换为Swift 3,它更新了几个API调用,因为Swift 3发生了所有重命名。这很好;我知道了。

但是,不太好的是,Swift 3似乎已经在 my Objective-C类中重命名了一个方法。我拥有Objective-C类,并且调用了我想要的方法:readDeliveryInfoItems。但是现在,在转换为Swift 3后,我不能再在我的Swift类中调用.readDeliveryInfoItems()了。它告诉我它已重命名为.readItems()

这没有任何意义。而Objective-C类仍然调用方法readDeliveryInfoItems,因此这里有一些内容。

我尝试将Objective-C readDeliveryInfoItems方法重命名为readDeliveryInfo,构建(Swift失败,因为它表示readInfo()方法不存在,这很好) ,然后将方法重命名为readDeliveryInfoItems。但是,当我在此之后构建时,Swift会重新认为该方法被称为readInfo()。我希望这会欺骗Xcode刷新Swift桥接并将方法重命名为正确的名称readDeliveryInfoItems(),但事实并非如此。

我该如何解决这个问题?

更新以添加更多信息

我的Objective-C类的接口有这个函数声明:

- (nullable NSArray<XMPPDeliveryInfoItem *> *)readDeliveryInfoItems;

但是在该类的Generated Interface(参见MartinR&#39;以下评论)中,函数声明就是:

open func readItems() -> [XMPPDeliveryInfoItem]?

该类中还有其他与readDeliveryInfoItems函数类似的函数,例如:{/ p>

- (nullable NSArray<XMPPDeliveryInfoItem *> *)sentDeliveryInfoItems;

它们在Generated Interface中看起来是正确的:

open func sentDeliveryInfoItems() -> [XMPPDeliveryInfoItem]?

所以我无法弄清楚为什么我只用一个功能来解决这个问题。

2 个答案:

答案 0 :(得分:14)

翻译过程详见

你问题的相关部分是(强调我的):

  

从方法的基本名称修剪封闭类型的匹配项   只要匹配在动词之后开始。例如,

extension UIViewController {
  func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)? = nil)
}
     

变为:

extension UIViewController {
  func dismissAnimated(flag: Bool, completion: (() -> Void)? = nil)
}

这个修剪算法 - 据我所见 - 实现于 StringExtras.cpp(并使用大量的启发式方法), 和PartsOfSpeech.def 包含被视为动词的单词列表,例如

VERB(dismiss)
VERB(read)
VERB(send)

VERB(sent)。这就解释了为什么 - 稍微简化你的例子 -

@interface DeliveryInfo : NSObject
-(void)readDeliveryInfoItems;
-(void)sentDeliveryInfoItems;
@end

变为

open class DeliveryInfo : NSObject {
    open func readItems()
    open func sentDeliveryInfoItems()
}

在动词“read”之后修剪类型名称,但在动词之后不修剪 非动词“发送”。 (您可以通过更改第二种方法来验证 名称为sendDeliveryInfoItems,然后映射到sendItems()。)

您可以使用NS_SWIFT_NAME覆盖映射:

-(void)readDeliveryInfoItems NS_SWIFT_NAME(readDeliveryInfoItems());

答案 1 :(得分:0)

粗略地说(而且我过于简单化),如果方法名称的后缀是与返回类型匹配的动词对象,则后缀将被删除。

一个更简单的例子是一个名为readString的方法,它返回一个NSString。

你的方法属于这些参数(我告诉你我过于简单,但你可以大致看出这是怎么回事),所以你得到了治疗。

就个人而言,我认为这是一个错误,特别是因为在某些情况下,更改可能会导致名称冲突,并且调用方法不可能(特别是当Objective-C API不属于您时)你不能改变它)。有关示例,请参阅此问题:Swift 3 (Omit Needless Words) causing two functions to have the same name