简体   繁体   English

调用Objective-Swift中的C委托方法

[英]Calling Objective - C delegate method in swift

I have a method declared in Objective-C protocol: 我有一个在Objective-C协议中声明的方法:

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

I want to use this method as callback in my .swift file. 我想将此方法用作.swift文件中的回调。 My question what is difference between using chatServiceChatDidConnect method directly in class body or adding it as part of extension: 我的问题是直接在类主体中使用chatServiceChatDidConnect方法或将其添加为扩展的一部分有什么区别:

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

or 要么

class Chat: NSObject, QMChatConnectionDelegate
{
...
}

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

and do I need to declare it as extension Chat : QMChatConnectionDelegate {} or just extension Chat {} 我是否需要将其声明为extension Chat : QMChatConnectionDelegate {}或只是extension Chat {}

First of all extension declaration is valid only from the file scope, so your second example should look like that: 首先,扩展名声明仅在文件范围内有效,因此您的第二个示例应如下所示:

class Chat: NSObject
{
...
}

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

Secondly you shouldn't re-declare protocol conformance in both class declaration and extension. 其次,您不应在类声明和扩展中都重新声明协议一致性。

You should treat Swift extension more or less like categories in Objective-C. 您应该或多或少像对待Objective-C中的类别一样对待Swift扩展。

Answering your questions, there is no big difference if you declare method conforming to a protocol directly in the class scope or in the extension. 回答您的问题,如果直接在类范围或扩展中声明符合协议的方法,则没有太大区别。 Adding protocol conformance in extensions can have several benefits: 在扩展中添加协议一致性可以带来以下好处:

  1. You can add methods implementing certain protocol in a separate file 您可以在单独的文件中添加实现某些协议的方法
  2. You can add protocol conformance to existing classes, without modifying their body. 您可以向现有类添加协议一致性,而无需修改其主体。 So in the end you can add protocol conformance to 3rd party classes 因此,最后您可以向第三方类添加协议一致性
  3. It allows for a nice logical organization of your source code. 它允许对源代码进行合理的逻辑组织。

There are two questions being asked here, so I'll try to address both of them as directly as possible. 这里有两个问题,因此,我将尝试尽可能直接解决这两个问题。


What is difference between using chatServiceChatDidConnect method directly in class body or adding it as part of extension? 直接在类主体中使用chatServiceChatDidConnect方法或将其添加为扩展的一部分有什么区别?

Depending on what you mean by "difference", the answer is either "nothing" or "very little". 取决于您所说的“差异”是什么,答案是“什么都没有”或“很小”。

Once your project is compiled, there will be no difference . 项目编译后,就不会有任何区别 During compilation, it might take slightly longer, but I doubt the difference is noticeable enough to care. 在编译过程中,它可能会花费更长的时间,但是我怀疑这种差异是否足够明显。 During development, the difference is mostly organizational, but perhaps partly architectural. 在开发过程中,差异主要是组织上的,但可能是部分架构上的。

If you do not move the extension to a separate file, the difference is going to be purely organizational. 如果您不将扩展名移至单独的文件,则区别将纯粹是组织上的。 If you have a class conforming to multiple protocols or particularly large protocols, organizing the protocol conformance into extensions can be beneficial when it comes to human-parsing of the class. 如果您的类符合多种协议或特别大的协议,那么在对类进行人为解析时,将协议符合性组织成扩展可能会很有用。

If you do move the extension into a separate file, you can obtain some architectural differences as well when we consider how the private access modifier works in Swift (or also the default internal when we consider that the extension could be not just a different file, but a different module, but for simplicity sake, let's focus on private ). 如果您确实将扩展名移到一个单独的文件中,那么当我们考虑private访问修饰符在Swift中的工作方式时,也可以获得一些体系结构上的差异(或者当我们考虑扩展名不只是一个不同的文件时,也可以使用默认的internal ,但使用不同的模块,但是为了简单起见,我们将重点放在private

Consider conforming to a UITableViewDataSource protocol. 考虑遵守UITableViewDataSource协议。 Conceivably, we might want some helper methods when it comes to returning a cell from tableView(_:cellForRowAtIndexPath:) , and if that's the case, tableView(_:cellForRowAtIndexPath:) is probably the only method that actually needs to call those methods. 可以想象,在从tableView(_:cellForRowAtIndexPath:)返回单元格时,我们可能需要一些辅助方法,如果是这种情况, tableView(_:cellForRowAtIndexPath:)可能是唯一实际需要调用这些方法的方法。 If that's the case, we can create the protocol conformance in an extension in a separate file and mark all of the helper methods as private . 如果是这种情况,我们可以在扩展名中的单独文件中创建协议一致性,并将所有帮助程序方法标记为private Now we've narrowed the scope of those helper methods to just that extension (which should be the only place that needs it). 现在,我们将这些辅助方法的范围缩小到仅该扩展名(应该是唯一需要它的地方)。


Do I need to declare it as extension Chat: QMChatConnectionDelegate {} or just extension Chat {} ? 我需要将其声明为extension Chat: QMChatConnectionDelegate {}还是仅声明extension Chat {}

The answer to this is it depends . 答案是,要看情况

Certainly, you don't need to mark your class as conforming to a protocol in multiple places. 当然,您无需在多个地方将您的类标记为符合协议。 Just one will do. 只有一个会做。 And while extensions can have different access level than the class they extend (a private extension of an internal class for example), they can not have an access level broader than the class they extend (a public extension of an internal class is not allowed, for example). 而且,尽管扩展名的访问级别与其扩展的类不同(例如, internal类的private扩展),但扩展名的访问级别不能大于其扩展的类(不允许internal类的public扩展,例如)。

What makes most sense to me is to not mark the class as conforming to the protocol but mark the extension as conforming to the protocol: 对我来说最有意义的是不要将类标记为符合协议,而是将扩展标记为符合协议:

class Chat: NSObject {}
extension Chat: QMChatConnectionDelegate {}

Importantly, when we create our classes & extensions like this, it keeps our code quite modular. 重要的是,当我们像这样创建我们的类和扩展时,它使我们的代码保持模块化。 Our class shouldn't rely on anything in the extension. 我们的班级不应依赖扩展中的任何内容。 It should function entirely without it, and removing the extension allow our class to still work properly (just not for using the QMChatConnection). 没有它,它应该完全起作用,并且删除扩展名使我们的类仍然可以正常工作(只是不使用QMChatConnection)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM