2014-10-25 12 views
41

Próbuję przekonwertować poniższy kod Objective-C na Swift. W moim kodzie Objective-C istnieje zmienna statyczna i jest dostępna z metody klasy.Właściwości statyczne w Swift

@implementation SomeClass 

static NSMutableArray *_items; 

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

@end 

Ponieważ nie można uzyskać dostęp do typów deklarowanych jak ten private var items = [AnyObject]() z funkcjami klasy w Swift, stworzyłem przechowywane własności do niego w ten sposób.

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

I próbuję wywołać metodę na to z funkcji klasy tak jak to.

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

Ale ten błąd wartość niezmienna typu „[AnyObject]” ma tylko zmutowanie członkowie nazwie „removeAll”.

Czy każdy może mi powiedzieć, co jest przyczyną tego błędu i jak go poprawić?

Dziękuję.

+0

Podczas próby rozwiązania problemu naprawiłem błąd kompilacji, wykonując "' var items: Array = []; '" –

Odpowiedz

72

Z tym kodem:

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

nie tworzysz przechowywanego mienia - zamiast to właściwość komputerowej, a najgorsze jest to, że za każdym razem, gdy dostęp do niej, tworzona jest nowa instancja [AnyObject], więc cokolwiek dodasz do niego, zostanie utracone, gdy tylko jego wzmianka wykracza poza zakres.

Co do błędu, statyczna właściwość obliczona zwraca niezmienna kopię tablicy, którą tworzysz w swoim ciele, więc nie można użyć dowolnej metody tablicy zadeklarowanej jako mutating - i removeAll jest jednym z nich. Powodem, dla którego jest on niezmienny, jest to, że zdefiniowałeś gettera, ale nie setera.

Obecnie zajęcia Swift nie obsługują właściwości statyczne, ale kodowanym zrobić - obejście często używam jest zdefiniowanie wewnętrzną struct:

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

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

Jeśli chcesz pozbyć się Static struktury Za każdym razem kiedy odnoszą się do właściwości items, wystarczy zdefiniować otoki obliczoną właściwość:

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

tak, że nieruchomość może być dostępne po prostu jako:

SomeClass.items.append("test") 
+3

Dzięki za odpowiedź. Nie podobało mi się dołączanie nazwy struktury wszędzie, więc zdefiniowałem właściwość obliczeniową o tej samej nazwie, co właściwość statyczna i uzyskuję do niej dostęp. Pomysł został zaczerpnięty z [tutaj] (http://stackoverflow.com/a/24924535/1077789). Czy to w porządku? – Isuru

+0

Tak, to dobrze - zaktualizowano odpowiedź, aby dodać tę przypadek. – Antonio

23

Aktualizacja do Swift1.2


W Swift1.2 [Xcode6.3], można zadeklarować właściwości statycznych za pomocą słowa kluczowego static, również można zadeklarować metody statyczne za pomocą słowa kluczowego lub statyczne klasy.

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

Edycja:

Różnica static i class modyfikatora jest static tylko alias „urządzenia końcowego”, a więc metodami modyfikowane static nie może być zmienione podklasy.

Dzięki @ Maiaux za

+4

Warto wspomnieć, że różnica między "class func" i "static func" polega na tym, że poprzednią można zastąpić w podklasie, więc nie są one dokładnie takie same. From The Swift Programming Language: "Klasy mogą również używać słowa kluczowego class, aby umożliwić podklasom nadpisanie implementacji tej klasy przez nadklasę". – Maiaux

+1

Testuję to, kiedy wrócę do domu, ale jest to dobre pytanie: czy Swift 1.2 obsługuje ** własności klasy **? –

+2

@MAGNAWS Swift 1.2 obsługuje właściwości obliczane ** class **. Jednak obecnie nie obsługuje jeszcze ** klasy ** właściwości zapisanych. – tounaobun

1

jeszcze instrukcji Swift 2 nadal twierdzi tylko wyliczenie struktury ond może używać statycznych properities sklepu.

Powiązane problemy