【问题标题】:Static properties in SwiftSwift 中的静态属性
【发布时间】:2014-12-21 10:42:36
【问题描述】:

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

@implementation SomeClass

static NSMutableArray *_items;

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

@end

由于您无法从 Swift 中的类函数中访问像 private var items = [AnyObject]() 这样声明的类型,因此我为它创建了这样的存储属性。

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

我正在尝试从这样的类函数中调用它的方法。

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

但我收到此错误“[AnyObject]”类型的不可变值只有名为“removeAll”的变异成员

谁能告诉我这个错误的原因是什么以及如何纠正它?

谢谢。

【问题讨论】:

  • 在尝试解决您的问题时,我通过执行“var items:Array<AnyObject> = [];”修复了您的编译错误

标签: ios class swift static-methods static-members


【解决方案1】:

使用此代码:

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

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

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

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

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

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

如果您想在每次引用 items 属性时都摆脱 Static 结构,只需定义一个包装计算属性即可:

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

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

SomeClass.items.append("test")

【讨论】:

  • 感谢您的回复。我不喜欢在任何地方附加结构名称,所以我定义了一个与静态属性同名的计算属性并通过它访问它。从here 得到这个想法。这样可以吗?
【解决方案2】:

更新到 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)
    }
}

编辑:

staticclass修饰符的区别在于static只是“类final”的别名,所以用static修改的方法不能在子类中被覆盖。

感谢@Maiaux 的

【讨论】:

  • 值得一提的是,“class func”和“static func”的区别在于前者可以在子类中被覆盖,所以它们并不完全相同。来自 The Swift Programming Language:“类也可以使用 class 关键字来允许子类覆盖超类对该方法的实现”。
  • 我回家后会对此进行测试,但这是一个很好的问题:Swift 1.2 是否支持 class 属性?
  • @MAGNAWS Swift 1.2 确实支持 class 计算属性。但是目前它还不支持 class 存储属性。
  • @Benson Tommy 谢谢!当我回到家时,我想通了。有趣的是,它们不允许我们覆盖属性,但它们确实允许我们覆盖 typealias,我认为这对于协议来说有点酷。
【解决方案3】:

然而 Swift 2 的手册仍然声称只是枚举和结构可以使用静态存储属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2019-06-19
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多