ios Swift 中类的“初始化”类方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24137212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"initialize" class method for classes in Swift?
提问by aleclarson
I'm looking for behavior similar to Objective-C's +(void)initialize
class method, in that the method is called once when the class is initialized, and never again thereafter.
我正在寻找类似于 Objective-C 的+(void)initialize
类方法的行为,因为该方法在类初始化时被调用一次,此后不再调用。
A simple class init () {}
in a class
closure would be really sleek! And obviously when we get to use "class var
s" instead of "static var
s in a struct closure", this will all match really well!
一个简单class init () {}
的class
闭合将非常时尚!很明显,当我们在结构闭包中使用“ class var
s”而不是“ static var
s”时,这一切都会非常匹配!
采纳答案by aleclarson
If you have an Objective-C class, it's easiest to just override +initialize
. However, make sure subclassesof your class also override +initialize
or else your class's +initialize
may get called more than once! If you want, you can use dispatch_once()
(mentioned below) to safeguard against multiple calls.
如果您有一个 Objective-C 类,最简单的方法是覆盖+initialize
. 但是,请确保您的类的子类也被覆盖+initialize
,否则您的类+initialize
可能会被多次调用!如果需要,您可以使用dispatch_once()
(如下所述)来防止多次调用。
class MyView : UIView {
override class func initialize () {
// Do stuff
}
}
If you have a Swift class, the best you can get is dispatch_once()
inside the init()
statement.
如果你有一个 Swift 类,你能得到的最好的就是dispatch_once()
在init()
语句中。
private var once = dispatch_once_t()
class MyObject {
init () {
dispatch_once(&once) {
// Do stuff
}
}
}
This solution differs from +initialize
(which is called the first time an Objective-C class is messaged) and thus isn't a true answer to the question. But it works good enough, IMO.
此解决方案不同于+initialize
(第一次向 Objective-C 类发送消息时称为),因此不是问题的真正答案。但它工作得很好,IMO。
回答by Binarian
There is no type initializerin Swift.
Swift 中没有类型初始值设定项。
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializerthat can assign a value to a stored type property at initialization time.”
“与存储的实例属性不同,您必须始终为存储的类型属性提供默认值。这是因为类型本身没有可以在初始化时为存储的类型属性赋值的初始化程序。”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
摘自:Apple Inc. “The Swift Programming Language”。电子书。
You could use a type propertywhich default value is a closure. So the code in the closure would be executed when the type property(or class variable) is set.
您可以使用默认值为闭包的类型属性。因此,当设置类型属性(或类变量)时,将执行闭包中的代码。
class FirstClass {
class var someProperty = {
// you can init the class member with anything you like or perform any code
return SomeType
}()
}
But class stored properties not yet supported
(tested in Xcode 8).
但是class stored properties not yet supported
(在 Xcode 8 中测试)。
One answer is to use static
, it is the same as class final
.
一个答案是使用static
,它与class final
.
Good link for that is
好的链接是
Setting a Default Property Value with a Closure or Function
使用闭包或函数设置默认属性值
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
摘自:Apple Inc. “The Swift Programming Language”。电子书。
Code example:
代码示例:
class FirstClass {
static let someProperty = {
() -> [Bool] in
var temporaryBoard = [Bool]()
var isBlack = false
for i in 1...8 {
for j in 1...8 {
temporaryBoard.append(isBlack)
isBlack = !isBlack
}
isBlack = !isBlack
}
print("setting default property value with a closure")
return temporaryBoard
}()
}
print("start")
FirstClass.someProperty
Prints
印刷
start
setting default property value with a closure
开始
使用闭包设置默认属性值
So it is lazy evaluated.
所以它是懒惰的评估。
回答by newacct
For @objc
classes, class func initialize()
definitely works, since +initialize
is implemented by the Objective-C runtime. But for "native" Swift classes, you'll have to see the other answers.
对于@objc
类,class func initialize()
肯定有效,因为它+initialize
是由 Objective-C 运行时实现的。但是对于“原生”Swift 类,您必须查看其他答案。
回答by Ian Bytchek
@aleclarson nailed it, but as of recent Swift 4 you cannot directly override initialize
. You still can achieve it with Objective-C and categories for classes inheriting from NSObject
with a class / static swiftyInitialize
method, which gets invoked from Objective-C in MyClass.m
, which you include in compile sources alongside MyClass.swift
:
@aleclarson 搞定了,但从最近的 Swift 4 开始,你不能直接覆盖initialize
. 您仍然可以使用 Objective-C 实现它,并NSObject
使用类/静态swiftyInitialize
方法继承类的类别,该方法从 Objective-C in 中调用MyClass.m
,您将其包含在编译源中MyClass.swift
:
# MyView.swift
import Foundation
public class MyView: UIView
{
@objc public static func swiftyInitialize() {
Swift.print("Rock 'n' roll!")
}
}
# MyView.m
#import "MyProject-Swift.h"
@implementation MyView (private)
+ (void)initialize { [self swiftyInitialize]; }
@end
If your class cannot inherit from NSObject
and using +load
instead of +initialize
is a suitable fit, you can do something like this:
如果你的类不能继承NSObject
和使用+load
而不是+initialize
合适的,你可以做这样的事情:
# MyClass.swift
import Foundation
public class MyClass
{
public static func load() {
Swift.print("Rock 'n' roll!")
}
}
public class MyClassObjC: NSObject
{
@objc public static func swiftyLoad() {
MyClass.load()
}
}
# MyClass.m
#import "MyProject-Swift.h"
@implementation MyClassObjC (private)
+ (void)load { [self swiftyLoad]; }
@end
There are couple of gotchas, especially when using this approach in static libraries, check out the complete poston Medium for details! ??
有几个问题,尤其是在静态库中使用这种方法时,请查看Medium 上的完整帖子了解详细信息!??
回答by Cy-4AH
You can use stored type properties instead of initialize
method.
您可以使用存储类型属性而不是initialize
方法。
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
}
But since stored types properties are actually lazily initialized on their first access, you will need refer them somewhere. You can do this with ordinary stored property:
但是由于存储类型属性实际上是在第一次访问时延迟初始化的,因此您需要在某处引用它们。你可以用普通的存储属性来做到这一点:
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
private let initializer: Void = SomeClass.initializer
}
回答by Bryan Chen
I can't find any valid use case to have something like +[initialize]
in Swift. Maybe this explains way it does not exist
我+[initialize]
在 Swift 中找不到任何有效的用例。也许这解释了它不存在的方式
Why do we need +[initialize]
in ObjC?
为什么我们需要+[initialize]
在 ObjC 中?
To initialize some global variable
初始化一些全局变量
static NSArray *array;
+ (void)initialize {
array = @[1,2,3];
}
which in Swift
在 Swift 中
struct Foo {
static let array = [1,2,3]
}
To do some hack
做一些黑客
+ (void)initialize {
swizzle_methodImplementation()
}
which is not supported by Swift (I can't figure out how to do it for pure Swift class/struct/enum)
Swift 不支持它(我不知道如何为纯 Swift 类/结构/枚举做到这一点)