web-dev-qa-db-fra.com

Variables de classe non encore prises en charge

Je commence mon projet avec un contrôleur de vue divisé en tant que contrôleur de vue initial et le lance automatiquement à partir du storyboard.

Généralement, une application avec cette interface utilisateur a n et un seul contrôleur de vue fractionnée en tant que root. Je crée donc une variable statique dans la sous-classe et la configure lors de l'initialisation.

Donc, je veux essayer ce comportement avec Swift.

J'ai lu le livre du guide de langage de programmation Swift sur iBook concernant les propriétés de type (avec les mots clés static et class)) et en essayant un morceau de code pour le travail:

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;
    }
}

mais j'ai compris quand Xcode dit que le mot clé class pour les propriétés du type n'était pas encore supporté.

error detail in image

Avez-vous une solution pour le faire?

94
Vincent Saluzzo

Swift prend maintenant en charge les variables statiques dans les classes. Ce n'est pas exactement la même chose qu'une variable de classe (car elles ne sont pas héritées par les sous-classes), mais cela vous rapproche beaucoup:

class X {
  static let y: Int = 4
  static var x: Int = 4
}

println(X.x)
println(X.y)

X.x = 5

println(X.x)
37
Bill

L'incorporation d'une structure peut très bien fonctionner comme solution de contournement:

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 propriété de type calculée SomeClass.workaroundClassVariable peut ensuite être utilisée comme s'il s'agissait d'une propriété de type stockée.

74
glessard

Il semble être possible de déclarer des variables avec une durée de stockage statique dans la portée du fichier (comme en C):

var sharedInstance: SplitViewController? = nil

class SplitViewController: UISplitViewController {
    ....
    func initialization() {
        sharedInstance = self
    }
}
20
Nikolai Ruhe

Ma méthode préférée consiste simplement à utiliser une étendue de fichier privé var en dehors de la classe, puis à implémenter des getters et des setters classe/statique:

private var _classVar: Int = 0;

class SomeClass
{
    public class var classVar: Int
    {
        get { return _classVar }
        set { _classVar = newValue }
    }
}
14
BobDickinson

À partir de Swift 1.2 (disponible à partir de Xcode 6.3b1 et versions ultérieures), static les propriétés et méthodes de la classe sont prises en charge.

class SomeClass
{
    static var someVariable: Int = 0
}
5
Andreas Ley

tilisation d'un modèle singleton dispatch_once dans Swift

Semble être la meilleure réponse à ce jour, en évitant l’utilisation d’une variable globale.

4
Gavin

Une solution assez similaire à var dans la portée du fichier mais plus personnalisable et proche de singleton consiste à utiliser une structure qui supporte var statique en tant que propriété de la classe.

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
}
4
Luc-Olivier

Ok, avec la solution de Nikolai qui fait le travail. Je publie mes modifications dans ce fil pour information

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
    }
}

et par exemple, dans mon appDelegate, je peux accéder à cette méthode statique comme ceci

SplitViewController.sharedInstance()!.presentsWithGesture = false
2
Vincent Saluzzo

Vous devez envelopper les variables de classe dans une variable de structure interne

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
1

Le libellé de l'erreur sous-entend fortement qu'il s'agira d'une fonctionnalité linguistique à l'avenir.

Vous souhaiterez peut-être recourir temporairement à la déclaration d'une variable de propriété dans le délégué d'application et la récupérer à partir de là. Pas idéal, certainement un anti-motif, mais vous donnerait un emplacement central pour récupérer le UISplitViewController lorsque cela est nécessaire.

1
Cezar

Il s’appelle le type de propriété dans Swift.

Vous définissez les propriétés de type avec le mot clé static. Pour les propriétés de type calculées pour les types de classe, vous pouvez utiliser le mot-clé class pour permettre aux sous-classes de remplacer l'implémentation de la superclasse. L'exemple ci-dessous montre la syntaxe des propriétés de type stockées et calculées:

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
    }
}

Lire la suite sur le lien ci-dessous,

https://developer.Apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//Apple_ref/doc/uid/TP40014097-CH14-ID254

0

Essaye ça:

class var instance: SplitViewController {
    return nil
}
0
fxchou123