在swift中调用Objective - C委托方法

时间:2016-03-04 11:40:31

标签: objective-c swift

我有一个在Objective-C协议中声明的方法:

@protocol QMChatConnectionDelegate <NSObject>
@optional
- (void)chatServiceChatDidConnect:(QMChatService *)chatService;

我想在我的.swift文件中使用此方法作为回调。我的问题是在类体中直接使用chatServiceChatDidConnect方法或将其作为扩展的一部分添加之间有什么区别:

class Chat: NSObject, QMChatConnectionDelegate
{
...
  func chatServiceChatDidConnect(chatService: QMChatService!) {
    print("connected")
  }
}

class Chat: NSObject, QMChatConnectionDelegate
{
...
}

extension Chat: QMChatConnectionDelegate {
    func chatServiceChatDidConnect(chatService: QMChatService!) {
        print("connected")
    }
}

我是否需要将其声明为extension Chat : QMChatConnectionDelegate {}extension Chat {}

2 个答案:

答案 0 :(得分:2)

首先,扩展声明仅在文件范围内有效,因此您的第二个示例应如下所示:

class Chat: NSObject
{
...
}

extension Chat : QMChatConnectionDelegate {
  func chatServiceChatDidConnect(chatService: QMChatService!) {
    print("connected")
}

其次,你不应该在类声明和扩展中重新声明协议一致性。

您应该将Swift扩展程序或多或少地视为Objective-C中的类别。

回答您的问题,如果您在类范围或扩展中直接声明符合协议的方法,则没有太大区别。 在扩展中添加协议一致性可以有几个好处:

  1. 您可以在单独的文件中添加实现特定协议的方法
  2. 您可以向现有类添加协议一致性,而无需修改其正文。因此,最后您可以将协议一致性添加到第三方类
  3. 它允许对源代码进行良好的逻辑组织。

答案 1 :(得分:2)

这里有两个问题,所以我会尝试尽可能直接地解决这两个问题。

  

直接在类体中使用chatServiceChatDidConnect方法或将其作为扩展的一部分添加有什么区别?

根据你的意思和差异&#34;,答案是&#34;什么都不是&#34;或者&#34;很少&#34;。

编译完项目后,无差异。在编译期间,可能需要稍微长一些,但我怀疑差异是否足以引起关注。在开发过程中,差异主要在于组织,但可能部分是建筑。

如果您不将扩展程序移动到单独的文件中,那么差异将完全是组织的。如果你有一个符合多种协议或特别大的协议的类,那么在人类解析类时,将协议一致性组织成扩展可能是有益的。

如果您确实将扩展程序移动到单独的文件中,那么当我们考虑private访问修饰符在Swift中的工作方式时(或者在我们考虑时也是默认的internal),您也可以获得一些体系结构差异扩展可能不仅仅是一个不同的文件,而是一个不同的模块,但为了简单起见,让我们关注private)。

考虑遵守UITableViewDataSource协议。可以想象,在从tableView(_:cellForRowAtIndexPath:)返回单元格时,我们可能需要一些辅助方法,如果是这样的话,tableView(_:cellForRowAtIndexPath:)可能是实际需要调用这些方法的唯一方法。如果是这种情况,我们可以在单独文件的扩展中创建协议一致性,并将所有帮助方法标记为private。现在我们已经将这些辅助方法的范围缩小到只有那个扩展(这应该是唯一需要它的地方)。

  

我是否需要将其声明为extension Chat: QMChatConnectionDelegate {}extension Chat {}

答案是取决于

当然,您不需要在多个地方标记您的课程符合协议。只有一个人会这样做。虽然扩展可以具有与它们扩展的类不同的访问级别(例如private类的internal扩展名),但它们的访问级别不能超出它们扩展的类({{{例如,不允许扩展public类。

对我来说最有意义的是将该类标记为符合协议,但将扩展标记为符合协议:

internal

重要的是,当我们创建我们的课程&amp;像这样的扩展,它使我们的代码非常模块化。我们班不应该依赖扩展中的任何东西。它应该完全没有它,并删除扩展允许我们的类仍然正常工作(只是不使用QMChatConnection)。