ios - descargar - swift download
¿"Inicializar" método de clase para las clases en Swift? (5)
@aleclarson lo clavó, pero a partir de Swift 4 reciente no puede anular directamente la initialize
. Aún puede lograrlo con Objective-C y categorías para las clases que se heredan de NSObject
con un método de clase / static swiftyInitialize
, que se invoca desde Objective-C en MyClass.m
, que incluye en las fuentes de compilación junto con 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
Si su clase no puede heredar de NSObject
y usar +load
lugar de +initialize
es un ajuste adecuado, puede hacer algo como esto:
# 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
¡Hay un par de errores, especialmente cuando se utiliza este enfoque en bibliotecas estáticas, echa un vistazo a la post completa en Medio para más detalles! ✌️
Estoy buscando un comportamiento similar al método de clase de +(void)initialize
Objective-C, en el que el método se llama una vez cuando se inicializa la clase, y nunca más después.
¡Una simple class init () {}
en un cierre de class
sería realmente elegante! Y, obviamente, cuando usamos " class var
s" en lugar de " static var
s en un cierre de estructura", ¡todo esto coincidirá realmente bien!
No hay inicializador de tipo en Swift.
“A diferencia de las propiedades de instancia almacenadas, siempre debe asignar un valor predeterminado a las propiedades de tipo almacenado. Esto se debe a que el tipo en sí no tiene un inicializador que pueda asignar un valor a una propiedad de tipo almacenado en el momento de la inicialización ".
Extracto de: Apple Inc. "El lenguaje de programación Swift". iBooks .
Podría usar una propiedad de tipo cuyo valor predeterminado es un cierre. Por lo tanto, el código en el cierre se ejecutaría cuando se establece la propiedad de tipo (o variable de clase).
class FirstClass {
class var someProperty = {
// you can init the class member with anything you like or perform any code
return SomeType
}()
}
Pero class stored properties not yet supported
(probadas en Xcode 8).
Una respuesta es usar static
, es lo mismo que la class final
.
Buen enlace para eso es
Configuración de un valor de propiedad predeterminado con un cierre o una función
Extracto de: Apple Inc. "El lenguaje de programación Swift". iBooks .
Ejemplo de código:
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
Huellas dactilares
comienzo
establecer el valor de propiedad predeterminado con un cierre
Por eso es perezoso evaluado.
No puedo encontrar ningún caso de uso válido para tener algo como +[initialize]
en Swift. Tal vez esto explique la forma en que no existe.
¿Por qué necesitamos +[initialize]
en ObjC?
Inicializar alguna variable global.
static NSArray *array;
+ (void)initialize {
array = @[1,2,3];
}
que en Swift
struct Foo {
static let array = [1,2,3]
}
Para hacer un poco de hack
+ (void)initialize {
swizzle_methodImplementation()
}
que no es compatible con Swift (no puedo averiguar cómo hacerlo para Swift class / struct / enum)
Para @objc
clases @objc
, la class func initialize()
definitivamente funciona, ya que +initialize
es implementado por el tiempo de ejecución de Objective-C. Pero para las clases de Swift "nativas", tendrás que ver las otras respuestas.
Si tiene una clase de Objective-C, es más fácil simplemente anular +initialize
. Sin embargo, asegúrese de que las subclases de su clase también anulen +initialize
o, de lo contrario, la clase +initialize
su clase puede recibir llamadas más de una vez. Si lo desea, puede usar dispatch_once()
(mencionado a continuación) para protegerse contra múltiples llamadas.
class MyView : UIView {
override class func initialize () {
// Do stuff
}
}
Si tiene una clase Swift, lo mejor que puede obtener es dispatch_once()
dentro de la declaración init()
.
private var once = dispatch_once_t()
class MyObject {
init () {
dispatch_once(&once) {
// Do stuff
}
}
}
Esta solución difiere de +initialize
(que se denomina la primera vez que se envía un mensaje a una clase de Objective-C) y, por lo tanto, no es una respuesta verdadera a la pregunta. Pero funciona bastante bien, OMI.