当前位置: 首页 > 面试题库 >

如何在Swift中初始化init

邓毅
2023-03-14
问题内容

我正在跟踪Swift和Objective-C Runtime,它适用于常规方法。

我喜欢使用init方法,据我了解,init就像一个类方法。因此,我尝试将初始化作为实例和类方法。但这似乎不起作用

我可以使用Objective C使其工作,只是想知道如何在Swift中使其工作

摘录自我的要旨

dispatch_once(&Static.token) {
            let originalSelector = Selector("init:source:destination:")
            let swizzledSelector = Selector("ftg_init:source:destination:")

            let originalMethod = class_getClassMethod(self, originalSelector)
            let swizzledMethod = class_getClassMethod(self, swizzledSelector)

            let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

            if didAddMethod {
                class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }

问题答案:

为方法创建选择器时,应使用Obj C方法签名作为选择器的基础,因为使用Obj C运行时完成了模糊处理。

所以原来的选择器应该是

initWithIdentifier:source:destination:

现在,这有点奇怪,因为定义了init方法,因此第一个参数上的标签是必需的(identifier两次),所以实际上要使用的选择器是

ftg_initWithIdentifier:source:destination:

我能找到的唯一文档是关于从Obj C到Swift的翻译的,但看起来好像是从Swift到Obj C的相反。

接下来,init...是一个实例方法,因此您需要进行两项更改。您需要更改class_getClassMethodclass_getInstanceMethod并且需要classft_init...方法中删除。

因此,当所有事情都说完之后,您的代码应该看起来像这样(对我有用)

dispatch_once(&Static.token) {
    let originalSelector = Selector("initWithIdentifier:source:destination:")
    let swizzledSelector = Selector("ftg_initWithIdentifier:source:destination:")

    let originalMethod = class_getInstanceMethod(self, originalSelector)
    let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

    let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

    if didAddMethod {
        class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

func ftg_init(identifier identifier: String!,
    source: UIViewController,
    destination: UIViewController) -> UIStoryboardSegue {

    return ftg_init(identifier: identifier,
        source: source,
        destination: destination.ftg_resolve())
}


 类似资料:
  • 问题内容: 我无法使用AECoreDataUI的CoreDataTableViewController中的 Swift 3在iOS 10中进行初始化。 编译器抱怨 控制器现在正使用通用类型进行快速处理,但未正确推断实体类型。我已经明确尝试过: 也没有运气。 谢谢! 问题答案: 现在是通用的。也是通用的。因此,在声明变量时,必须使用通用声明,例如:

  • 问题内容: 我一直在尝试从Swift中初始化一个字符串。 苹果在NSString Cocoa文档 中说您必须使用以下代码: 但是,苹果没有提供任何用法或放置示例的示例。 我正在尝试将以下代码从Objective-C转换为Swift 我一直在尝试许多可能的语法,例如以下语法(当然它不起作用): 问题答案: 这是您应该如何初始化: Swift 2.X或更旧版本 Swift 3或更高版本: 本文档说明了

  • 问题内容: 为了将另一个问题分解为更小的部分,我尝试设置所有TextKit组件。但是,更改初始化方法后,我崩溃了。出于测试目的,我将该项目简化为以下内容: 崩溃时出现异常代码EXC_I386_GPFLT。该代码不是很明确。基本问题似乎归结为我如何初始化。 如果我更换 有了这个 然后就可以了。我究竟做错了什么? 问题答案: 看来,做事的方法是将NSLayoutManager添加到NSTextStor

  • 问题内容: 我无法按照以下代码初始化列表: 我遇到以下错误: 无法实例化类型 我该如何实例化? 问题答案: 如果你检查API,则会注意到它说: 作为一种手段,它无法实例化(不可能)。 如果你检查该链接,则会发现一些实现的: 所有已知的实施类: 那些可以实例化。使用它们的链接来了解有关它们的更多信息,即IE:知道哪个更适合你的需求。 三种最常用的可能是: 奖励: 你还可以使用,以更简单的方式使用值实

  • 问题内容: 我有一个初始化为的变量: 问题是,在某个时候,我需要重置此变量,以便在更改后可以再次初始化。但是如果我将类设置为可选的话,LLVM在尝试将它设置为时会给我一个错误。如果我只是使用将其重置在代码中的某个位置,它将最终显示为。 有没有一种方法可以使用并允许自己重置? 问题答案: 懒惰是明确的仅一次初始化。您要采用的模型可能只是按需初始化模型: 现在,只要是,它会被初始化并返回。可以通过设置

  • Swift 5.x String初始化、定义 1. 字面量初始化字符串 1.1 单行字面量字符串 let str = "some string" 1.2 字面量初始化多行字符串 let str = """ The white Rabbit put on his spectacles. "Where shell I begin, please your Majesty?" he asked. "