Статические свойства в 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" .
Кто-нибудь может рассказать мне, в чем причина этой ошибки и как ее исправить?
Спасибо.
Ответы
Ответ 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 по-прежнему утверждает, что только перечислимые структуры могут использовать свойства статического хранилища.