Swift已经弃用了macOS中的initialize()方法吗? [英] Is there an alternative to initialize() in macOS now that Swift has deprecated it?

查看:137
本文介绍了Swift已经弃用了macOS中的initialize()方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Objective-C声明一个类函数initialize(),在使用每个类之前,该函数对每个类都运行一次.除其他事项外,它通常用作交换方法实现(交换)的入口.在Swift 3.1中已弃用它.

Objective-C declares a class function, initialize(), that is run once for each class, before it is used. It is often used as an entry point for exchanging method implementations (swizzling), among other things. Its use was deprecated in Swift 3.1.

这是我曾经做过的事情:

This is what I used to do:

extension NSView {
    public override class func initialize() {
        // This is called on class init and before `applicationDidFinishLaunching`
    }
}

在没有initialize的情况下如何实现相同的目的?

How can I achieve the same thing without initialize?

我需要它作为框架,因此无需在AppDelegate中调用某些内容.我需要在applicationDidFinishLaunching之前调用它.

I need it for a framework, so requiring calling something in the AppDelegate is a no-go. I need it called before applicationDidFinishLaunching.

我非常喜欢解决方案.这正是我在寻找的东西,但它是针对iOS的.对于macOS,我需要它.有人可以建议使用该版本的macOS吗?

I really like this solution. It's exactly what I'm looking for, but it's for iOS. I need it for macOS. Could someone suggest a macOS version of that?

具体来说,我需要与此等效的功能,但对于macOS:

To be specific, I need the equivalent of this, but for macOS:

extension UIApplication {
    private static let runOnce: Void = {
        // This is called before `applicationDidFinishLaunching`
    }()

    override open var next: UIResponder? {
        UIApplication.runOnce
        return super.next
    }
}

我尝试覆盖NSApplication上的各种属性,但没有成功.

I've tried overriding various properties on NSApplication with no success.

解决方案必须使用纯Swift.没有Objective-C.

推荐答案

不,不存在initialize()的Swift替代方案,主要是因为Swift是静态分配的,因此无法拦截方法调用.而且,实际上不再需要了,因为该方法通常用于初始化Objective-C文件中的静态变量,并且在Swift中,静态/全局变量始终是惰性的,并且可以使用表达式的结果进行初始化(在Objective-C中是不可能的) C).

Nope, a Swift alternative to initialize() doesn't exist, mainly because Swift is statically dispatched, so method calls can't be intercepted. And is really no longer needed, as the method was commonly used to initialize static variables from Objective-C files, and in Swift static/global variables are always lazy and can be initialized with the result of an expression (thing not possible in Objective-C).

即使有可能实现类似的目标,我也不鼓励您在框架用户不知情的情况下隐式运行某些东西.我建议在库中的某处添加一个configure方法,并要求库的用户调用它.这样,他们可以控制初始化点.在没有我同意的情况下,与我链接但没有(或尚未使用)开始执行代码的框架相比,只有几件事情更糟糕了.

Even if it would be possible to achieve something similar, I would discourage you to implicitly run stuff without the knowledge of the framework users. I'd recommend to add a configure method somewhere in the library and ask the users of your library to call it. This way they have control over the initialization point. There are only a few things worser than having a framework that I linked against, but no longer (or not yet) using, to start executing code without my consent.

让框架用户可以控制何时启动框架代码是比较明智​​的选择.如果确实您的代码必须在应用程序生命周期的最开始运行,那么请框架用户在进行任何其他调用之前先对您的框架入口点进行调用.正确配置您的框架也符合他们的利益.

It's just saner to give framework users control over when they want the framework code to start. If indeed your code must run at the very beginning of the application lifecycle, then ask the framework users to make the call to your framework entry point before any other calls. It's also in their interest for your framework to be properly configured.

例如:

MyFramework.configure(with: ...)
// or
MyManager.start()

这篇关于Swift已经弃用了macOS中的initialize()方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆