[英]Swift Override Default Init No Subclass
Is it possible to override a default init without subclassing?是否可以在没有子类化的情况下覆盖默认初始化?
I want every instance of DateFormatter
created in my app to have the same locale
attached to it.我希望在我的应用程序中创建的每个DateFormatter
实例都附加相同的locale
。 Right now, upon each instance creation, I have to:现在,在创建每个实例时,我必须:
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX"
Is it possible to have this happen without the need to write out the locale every single time?是否有可能在不需要每次都写出语言环境的情况下发生这种情况? I'd prefer to not create a DateFormatter subclass as I feel that's a bit of overkill我宁愿不创建DateFormatter子类,因为我觉得这是一个有点矫枉过正
Thanks!谢谢!
There is no way to override an existing method of a class without subclassing it or modifying the source code (which you obviously can't do in case of built-in types).如果不继承类或修改源代码,就无法覆盖类的现有方法(对于内置类型,您显然不能这样做)。
However, for your specific case, you could simply add a method/static variable that returns a DateFormatter
specific to your needs.但是,对于您的特定情况,您可以简单地添加一个方法/静态变量,该变量返回特定于您的需要的DateFormatter
。
extension DateFormatter {
static func usPosix() -> DateFormatter {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
return dateFormatter
}
}
And then instead of calling let dateFormatter = DateFormatter()
, you do let dateFormatter = DateFormatter.usPosix()
然后不是调用let dateFormatter = DateFormatter()
,而是let dateFormatter = DateFormatter.usPosix()
While I personally HIGHLY advise against swizzling, that is certainly an option here.虽然我个人强烈建议不要使用 swizzling,但这当然是一个选择。
First, start by creating your own locale that you want to be used throughout your app:首先,首先创建您想要在整个应用程序中使用的自己的语言环境:
extension DateFormatter {
// Note the "@objc" here, this is necessary for altering the runtime logic
@objc var swizzledLocale: Locale {
return Locale(identifier: "en_US_POSIX")
}
}
Next, you'll want to tell Swift that whenever a DateFormatter
's locale is accessed, you want your new swizzledLocale
to be used instead:接下来,您需要告诉 Swift,每当访问DateFormatter
的语言环境时,您都希望使用新的swizzledLocale
:
// get reference to the two getter methods for the properties you want to "switch"
let orig = #selector(getter: DateFormatter.locale)
let new = #selector(getter: DateFormatter.swizzledLocale)
let origMethod = class_getInstanceMethod(DateFormatter.self, orig)!
let newMethod = class_getInstanceMethod(DateFormatter.self, new)!
// performs the actual switch so that whenever "locale" is accessed in code, the returned value will be the value of "swizzledLocale"
method_exchangeImplementations(origMethod, newMethod)
And that's all there is to it!这就是全部! Now whenever you access any DateFormatter
's locale
, a Locale("en_US_POSIX")
will be returned.现在,每当您访问任何DateFormatter
的locale
,都会返回Locale("en_US_POSIX")
。
Some things to note: first, this will alter ALL instances of locale
, not just the locale
s that you personally use in your own code.需要注意的一些事情:首先,这将改变locale
所有实例,而不仅仅是您个人在自己的代码中使用的locale
。 That is, if there's any internal code that relies on a formatter's locale
, en_US_POSIX
will always be used.也就是说,如果有任何依赖于格式化程序locale
内部代码,则将始终使用en_US_POSIX
。 Second, the second block of code (the one that performs the actual swizzling) should be called exactly one time;其次,第二个代码块(执行实际 swizzling 的那个)应该被调用一次; look into wrapping it in a dispatch_once
block to ensure it only runs once.考虑将它包装在dispatch_once
块中以确保它只运行一次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.