web-dev-qa-db-fra.com

Propriétés statiques dans Swift

J'essaie de convertir le code Objective-C suivant en Swift. Dans mon code Objective-C, il y a une variable statique et son accès à partir d'une méthode de classe.

@implementation SomeClass

static NSMutableArray *_items;

+ (void)someMethod {
    [_items removeAll];
}

@end

Comme vous ne pouvez pas accéder aux types déclarés comme ceci private var items = [AnyObject]() à partir de fonctions de classe dans Swift, j'ai créé une propriété stockée pour elle comme ceci.

class var items: [AnyObject] {
    return [AnyObject]()
}

Et j'essaye d'appeler une méthode dessus depuis une fonction de classe comme ça.

class func someFunction() {
    items.removeAll(keepCapacity: false)
}

Mais j'obtiens cette erreur La valeur immuable de type '[AnyObject]' n'a que des membres en mutation nommés 'removeAll'.

Quelqu'un peut-il me dire quelle est la cause de cette erreur et comment la corriger?

Merci.

43
Isuru

Avec ce code:

class var items: [AnyObject] {
    return [AnyObject]()
}

vous ne créez pas une propriété stockée - c'est une propriété calculée, et le pire, c'est que chaque fois que vous y accédez, une nouvelle instance de [AnyObject] est créé. Ainsi, quoi que vous ajoutiez, il est perdu dès que sa référence devient hors de portée.

En ce qui concerne l’erreur, la propriété statique calculée renvoie une copie immuable du tableau que vous créez dans son corps. Vous ne pouvez donc utiliser aucune des méthodes de tableau déclarées comme mutating - et removeAll en est une. d'eux. La raison pour laquelle il est immuable est que vous avez défini un getter, mais pas un setter.

Actuellement, les classes Swift ne prennent pas en charge les propriétés statiques, mais les structures - La solution de contournement que j'utilise souvent consiste à définir une structure interne:

class SomeClass {
    struct Static {
        static var items = [AnyObject]()
    }
}

SomeClass.Static.items.append("test")

Si vous voulez vous débarrasser de la structure Static à chaque fois que vous faites référence à la propriété items, définissez simplement une propriété calculée par le wrapper:

class var items: [AnyObject] {
    get { return Static.items }
    set { Static.items = newValue }
}

afin que la propriété soit accessible plus simplement comme:

SomeClass.items.append("test")
75
Antonio

Mise à jour vers Swift1.2


Dans Swift1.2 [Xcode6.3], vous pouvez déclarer des propriétés statiques à l'aide du mot clé static, ainsi que des méthodes statiques à l'aide du mot clé class ou static.

class SomeClass {

    // use static modifier to declare static properties.
    static var items: [AnyObject]!

    // use class modifier to declare static methods.
    class func classMethod() {

        items.removeAll(keepCapacity: false)
    }

    // use static modifier to declare static methods.
    static func staticMethod() {

        items.removeAll(keepCapacity: false)
    }
}

MODIFIER:

La différence entre static et class modificateur est que static n'est qu'un alias pour "class final", les méthodes modifiées avec static ne peuvent donc pas être remplacées dans sous-classes.

Merci @ Maiaux

23
tounaobun

Pourtant, le manuel pour Swift 2 affirme toujours qu'il suffit d'énumérer et que les structures peuvent utiliser des propriétés de magasin statiques.

1
user1785898