Swift中的静态属性

Isu*_*uru 43 static-methods class static-members ios swift

我正在尝试将以下Objective-C代码转换为Swift.在我的Objective-C代码中,有一个静态变量,它可以从类方法访问.

@implementation SomeClass

static NSMutableArray *_items;

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

@end
Run Code Online (Sandbox Code Playgroud)

因为你无法private var items = [AnyObject]()从Swift中的类函数访问这样声明的类型,所以我为它创建了一个存储属性.

class var items: [AnyObject] {
    return [AnyObject]()
}
Run Code Online (Sandbox Code Playgroud)

而我正试图从类函数中调用一个方法.

class func someFunction() {
    items.removeAll(keepCapacity: false)
}
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误类型'[AnyObject]'的不可变值只有名为'removeAll'的变异成员.

任何人都可以告诉我这个错误的原因是什么以及如何纠正它?

谢谢.

Ant*_*nio 75

使用此代码:

class var items: [AnyObject] {
    return [AnyObject]()
}
Run Code Online (Sandbox Code Playgroud)

你不是在创建一个存储的属性 - 而是它是一个计算属性,最糟糕的是每次你访问它时[AnyObject]都会创建一个新的实例,所以无论你添加什么,它一旦引用就会丢失范围.

至于错误,静态计算属性返回您在其主体中创建的数组的不可变副本,因此您不能使用任何声明为的数组方法mutating- 并且removeAll是其中之一.它是不可变的原因是因为你定义了一个getter,而不是一个setter.

目前Swift类不支持静态属性,但结构不支持 - 我经常使用的解决方法是定义内部结构:

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

SomeClass.Static.items.append("test")
Run Code Online (Sandbox Code Playgroud)

如果你想在Static每次引用items属性时去除结构,只需定义一个包装器计算属性:

class var items: [AnyObject] {
    get { return Static.items }
    set { Static.items = newValue }
}
Run Code Online (Sandbox Code Playgroud)

这样可以更简单地访问该属性:

SomeClass.items.append("test")
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回复.我不喜欢在任何地方附加结构名称,因此我定义了一个与静态属性同名的计算属性并通过它访问它.从[这里](http://stackoverflow.com/a/24924535/1077789)得到了想法.这个可以吗? (3认同)

tou*_*bun 23

更新为Swift1.2


在Swift1.2 [Xcode6.3]中,您可以使用关键字static声明静态属性,也可以使用关键字class或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)
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

staticclass修饰符之间的区别在于它static只是"类final"的别名,因此修改的方法static不能在子类中重写.

谢谢@Maiaux的

  • 值得一提的是,"class func"和"static func"之间的区别在于前者可以在子类中重写,因此它们并不完全相同.来自Swift编程语言:"类也可以使用class关键字来允许子类覆盖超类的该方法的实现". (4认同)
  • @MAGNAWS Swift 1.2确实支持**类**计算属性.但是目前它还不支持**类**存储属性. (2认同)