【问题标题】:Swift protocol as an init parameter called from Objective C classSwift 协议作为从 Objective C 类调用的 init 参数
【发布时间】:2017-09-06 10:51:52
【问题描述】:

我定义了一个快速协议,用于在 iOS 中测试 openUrl 功能。它看起来像这样:

protocol URLOpener {

    func open(_ url: URL, options: [String : Any], completionHandler completion: ((Bool) -> Void)?)
    func canOpenURL(_ url: URL) -> Bool

}

extension UIApplication: URLOpener {}

注意UIApplication 是符合此协议的类。

现在我有一个类,它采用对象URLOpener 类型来初始化该类

import Foundation
class GenericHandler : NSObject {

    required init(urlOpener: URLOpener) {
        super.init()
    }

    func aaa() {
        NBLog("aaaaa")
    }
}

我想使用 Objective C 中的这个 GenericHandler 类,但我给我一个错误,它找不到初始化程序。

  GenericHandler *handler = [[GenericHandler alloc] initWithUrlOpener:[UIApplication sharedApplication]];
        [handler aaa];

 No visible @interface for 'GenericHandler' declares the selector 'initWithUrlOpener:'

但是,如果我更改初始化程序以使其接受String 参数,那么它开始正常工作。

import Foundation
class GenericHandler : NSObject {

    required init(urlOpener: String) {
        super.init()
    }

    func aaa() {
        NBLog("aaaaa")
    }

}



GenericHandler *handler = [[GenericHandler alloc] initWithUrlOpener:@"test"];
        [handler aaa];

这很好用。谁能指导我 URLOpener 协议有什么问题,或者我如何使它与 URLOpener 参数一起工作。

【问题讨论】:

  • 尝试通过添加@objc protocol ...将协议公开到ObjC中
  • 当我这样做时Objective-C method openURL:options:completionHandler: provided by method open(_:options:completionHandler:) does not match the requirement's selector (open:options:completionHandler:)
  • 与protocol 超类一起玩,其中之一应该可以工作:protocol URLOpener: NSObjectProtocol,protocol URLOpener: NSObject,protocol URLOpener: class
  • 它们都不起作用。

标签: ios objective-c swift initialization bridging-header


【解决方案1】:

有点晚了,但我只是在同一个问题上挣扎。

您必须将 protocol 和 init 都暴露给 Objective-C。

@objc protocol URLOpener {
    func open(_ url: URL, options: [String : Any], completionHandler completion: ((Bool) -> Void)?)
    func canOpenURL(_ url: URL) -> Bool
}

extension UIApplication: URLOpener {}

-

import Foundation

class GenericHandler : NSObject {

    @objc required init(urlOpener: URLOpener) {
        super.init()
    }

    func aaa() {
        NBLog("aaaaa")
    }
}

您始终可以检查生成的头文件,以查看您的 Swift 代码是否在 Objective-C 中可用。请参阅“将 Swift 导入到 Objective-C”from the Apple docs 段落。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多