xcode - resueltos - Variables de clase aún no soportadas
importar clases en python (12)
Comienzo mi proyecto con un controlador de vista dividida como controlador de vista inicial y lo inicio automáticamente desde el guión gráfico.
Generalmente, una aplicación con esta UI tiene un único controlador de vista dividida como raíz, por lo que creo una variable estática en la subclase y la configuro cuando se realizó la inicialización.
Así que quiero probar este comportamiento con rapidez.
Leí la guía de lenguaje de programación Swift en iBook sobre propiedades de tipo (con palabras clave estáticas y de clase) y probando un fragmento de código para el trabajo:
import UIKit
class SplitViewController: UISplitViewController {
class func sharedInstance() -> SplitViewController {
return SplitViewController.instance
}
class let instance: SplitViewController = nil
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initialization()
}
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder);
self.initialization()
}
func initialization() {
SplitViewController.instance = self;
}
}
pero me di cuenta cuando Xcode dice que la palabra clave class para las propiedades de tipo aún no era compatible.
¿Tuviste una solución para hacer esto?
A partir de Swift 1.2 (disponible con Xcode 6.3b1 en adelante), se admiten propiedades y métodos de clases static
.
class SomeClass
{
static var someVariable: Int = 0
}
Debe envolver las variables de clase dentro de una variable de estructura interna
class Store{
var name:String
var address:String
var lat:Int
var long:Int
init(name:String, address:String, lat:Int, long:Int){
self.name = name
self.address = address
self.lat = lat
self.long=long
}
private struct FACTORY_INITIALIZED_FLAG { static var initialized: Bool = false
static var myStoreList:[Store]?
static func getMyStoreList()->[Store]{
if !initialized{
println("INITIALIZING")
myStoreList = [
Store(name: "Walmart", address: "abcd", lat: 10, long: 20),
Store(name: "JCPenny", address: "kjfnv", lat: 23, long: 34)
]
initialized = true
}
return myStoreList!
}
}
}
var a = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()
var b = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()
// only prints INITIALIZING once
Incrustar una estructura puede funcionar bien como una solución alternativa:
class SomeClass
{
// class var classVariable: Int = 0
// "Class variables not yet supported." Weird.
// Workaround:
private struct SubStruct { static var staticVariable: Int = 0 }
class var workaroundClassVariable: Int
{
get { return SubStruct.staticVariable }
set { SubStruct.staticVariable = newValue }
}
}
La propiedad de tipo calculado SomeClass.workaroundClassVariable se puede usar como si fuera una propiedad de tipo almacenada.
La redacción en el error implica que esta será una función de idioma en el futuro.
Es posible que desee recurrir temporalmente a la declaración de una variable de propiedad en el delegado de la aplicación y recuperarla desde allí. No es ideal, definitivamente es un anti-patrón, pero le daría un lugar central para recuperar el UISplitViewController
cuando sea necesario.
Mi método preferido es simplemente usar un ámbito de archivo privado var fuera de la clase y luego implementar class / get y setters estáticos:
private var _classVar: Int = 0;
class SomeClass
{
public class var classVar: Int
{
get { return _classVar }
set { _classVar = newValue }
}
}
Ok, con la solución de Nikolai que hace el trabajo. Publiqué mis cambios en este hilo para obtener información
var instance: SplitViewController? = nil
class SplitViewController: UISplitViewController {
class func sharedInstance() -> SplitViewController? {
return instance;
}
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initialization()
}
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder);
self.initialization()
}
func initialization() {
instance = self
}
}
y, por ejemplo, en mi appDelegate, puedo acceder a este método estático como este
SplitViewController.sharedInstance()!.presentsWithGesture = false
Parece posible declarar variables con duración de almacenamiento estático en el alcance del archivo (como en C):
var sharedInstance: SplitViewController? = nil
class SplitViewController: UISplitViewController {
....
func initialization() {
sharedInstance = self
}
}
Prueba esto:
class var instance: SplitViewController {
return nil
}
Se llama Propiedad Tipo en Swift.
Usted define propiedades de tipo con la palabra clave estática. Para las propiedades de tipos computados para los tipos de clase, puede usar la palabra clave class para permitir que las subclases anulen la implementación de la superclase. El siguiente ejemplo muestra la sintaxis de las propiedades de tipo almacenadas y calculadas:
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
Lea más en el siguiente enlace,
Swift ahora tiene soporte para variables estáticas en las clases. Esto no es exactamente lo mismo que una variable de clase (porque no son heredadas por subclases), pero te acerca bastante:
class X {
static let y: Int = 4
static var x: Int = 4
}
println(X.x)
println(X.y)
X.x = 5
println(X.x)
Una solución lo suficientemente similar a var en el alcance del archivo pero más personalizable y cercana a singleton es usar una estructura que soporte la var estática como propiedad de la clase
struct PersonSharedData {
static var backstore = ""
var data: String {
get { return PersonSharedData.backstore }
set { PersonSharedData.backstore = newValue }
}
}
class Person {
var shared=PersonSharedData() //<< pseudo class var
var family: String {
get { return shared.data }
set { shared.data=newValue }
}
var firstname = ""
var lastname = ""
var sexe: Sexe = .Unknown
}
Uso de un modelo de singleton dispatch_once en Swift
Parece ser la mejor respuesta hasta ahora, evitando el uso de una variable global.