2014-10-25 4 views
41

Я пытаюсь преобразовать следующий код Objective-C в Swift. В моем объектно-C-коде есть статическая переменная и ее доступ к методу класса.Статические свойства в Swift

@implementation SomeClass 

static NSMutableArray *_items; 

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

@end 

Поскольку вы не можете получить доступ типа, объявленный как этот private var items = [AnyObject]() из функций класса в Swift, я создал хранимое свойство для него, как это.

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

И я пытаюсь вызвать метод на нем из такой функции класса.

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

Но я получаю эту ошибку Неизменного значения типа '[AnyObject] только имеет мутируют член с именем «RemoveAll».

Может кто-нибудь скажет мне, в чем причина этой ошибки и как ее исправить?

спасибо.

+0

При попытке решить вашу проблему я исправил вашу ошибку компиляции, выполнив «var items: Array = [];' » –

ответ

72

С помощью этого кода:

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

вы не создаете хранимое свойство - вместо того, чтобы это вычисленное свойства, и хуже всего, что каждый раз, когда вы к нему доступ, новый экземпляр [AnyObject] создается, поэтому, что бы вы ни добавляли к нему, он теряется, как только его ссылка выходит за рамки.

Что касается ошибки, то статическое вычисляемое свойство возвращает неизменяемую копию массива, который вы создаете в своем теле, поэтому вы не можете использовать какой-либо метод массива, объявленный как mutating, и removeAll является одним из них. Причина, по которой это неизменна, состоит в том, что вы определили геттер, но не сеттер.

В настоящее время Swift классы не поддерживают статические свойства, но делать Структуры - обходной путь я часто использую, чтобы определить внутренний-структуру:

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

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

Если вы хотите избавиться от Static структуры каждый раз, когда вы обратитесь к items собственности, просто определить обертку вычисленного свойства:

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

так, что свойство можно получить более просто:

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

Спасибо за ответ. Мне не нравилось добавлять имя структуры везде, поэтому я определил вычисленное свойство с тем же именем, что и статическое свойство, и доступ к нему через него. Получил идею из [здесь] (http://stackoverflow.com/a/24924535/1077789). Это нормально? – Isuru

+0

Да, это нормально - обновленный ответ, чтобы добавить этот случай – Antonio

23

Обновлен Swift1.2


В Swift1.2 [Xcode6.3], вы можете объявить статические свойства, используя ключевое слово статическим, также вы можете объявить статические методы, используя класс ключевого слова или статичный.

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

РЕДАКТИРОВАТЬ:

Разница между static и class модификатора в том, что static просто псевдоним для «класса окончательного», поэтому методы, модифицированные static не могут быть переопределены в подклассах.

Спасибо @

+4

Возможно, стоит отметить, что разница между «func класса» и «static func» заключается в том, что первое может быть переопределено в подклассе, поэтому они не совсем одинаковы. Из языка Swift Programming: «Классы также могут использовать ключевое слово класса, чтобы позволить подклассам переопределять реализацию суперкласса этого метода». – Maiaux

+1

Я проверю это, когда вернусь домой, но это хороший вопрос: поддерживает ли Swift 1.2 ** класс ** свойства? –

+2

@MAGNAWS Swift 1.2 поддерживает ** класс ** вычисленные свойства. Однако в настоящее время он не поддерживает ** класс ** сохраненных свойств. – tounaobun

1

Yet руководство Maiaux для Swift 2 по-прежнему утверждает, просто перечислению ОНД структуры могут использовать статические хранилища properities.

Смежные вопросы