Подтвердить что ты не робот

Статические свойства в Swift

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

@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" .

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

Спасибо.

4b9b3361

Ответ 1

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

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

Ответ 2

Обновлен до Swift1.2


В Swift1.2 [Xcode6.3] вы можете объявлять статические свойства с помощью ключевого слова 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)
    }
}

EDIT:

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

Спасибо @Maiaux

Ответ 3

Тем не менее, руководство для Swift 2 по-прежнему утверждает, что только перечислимые структуры могут использовать свойства статического хранилища.