尚不支持类变量


93

我将拆分视图控制器作为初始视图控制器开始我的项目,然后从情节提要自动启动它。

通常,具有此UI的应用程序具有一个且只有一个拆分视图控制器作为根,因此我在子类中创建一个静态变量,并在完成初始化时对其进行设置。

所以我想尽快尝试这种行为。

我在iBook上阅读了有关Type属性(带有static和class关键字)的Swift编程语言指南,并尝试了一段代码来完成这项工作:

import UIKit

class SplitViewController: UISplitViewController {

    class func sharedInstance() -> SplitViewController {
        return SplitViewController.instance
    }

    class let instance: SplitViewController = nil

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.initialization()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder);
        self.initialization()
    }

    func initialization() {
        SplitViewController.instance = self;
    }
}

但是我弄清楚了何时Xcode说尚不支持类型属性的class关键字。

图像中的错误细节

您有解决方案吗?


如果将“ let”替换为“ var”会怎样?
ZunTzu 2014年

它产生相同的错误。
Cezar 2014年

1
这是第一颗种子,冷静一下。:)如果这本书说,它的支持,这是尚未公布,这是。甚至错误也说“还”
akashivskyy 2014年

1
是的,@ akashivskyy是您的原因,但可能是我的错误,有人可以解决此问题……
Vincent Saluzzo 2014年

1
@lespommes众所周知,Apple对即将发生的任何事情都保持沉默。让他们感到尴尬的是,由于他们大量发布其新的旗舰语言而缺少这种标准和明显的功能。在准备好认真使用Swift之前,还需要进行许多改进。
Hyperbole

Answers:


37

Swift现在支持类中的静态变量。这与类变量不完全相同(因为它们不是子类继承的),但它使您非常接近:

class X {
  static let y: Int = 4
  static var x: Int = 4
}

println(X.x)
println(X.y)

X.x = 5

println(X.x)

1
正如比尔所说,那不一样,但这是我所需要的!
Vincent Saluzzo

@VincentSaluzzo,(和Bill)此变量与类变量之间有什么区别?
skywinder

Apple文档最近已更改为更新状态:developer.apple.com/library/ios/documentation/Swift/Conceptual / ... 实际上,class关键字现在仅可用于计算属性,而静态仅用于所有类型属性(在枚举中,类或struct)
Vincent Saluzzo 2015年

@skywinder正如我在回答中提到的那样,真正的类变量可以由子类继承。静态变量不能。
比尔

@VincentSaluzzo苹果是否更新其文档?developer.apple.com/library/ios/documentation/Swift/Conceptual/…请看第四段:“对于值类型(即结构和枚举),您可以定义存储和计算的类型属性。对于类,您可以仅定义计算类型属性。”
fujianjin6471 2015年

73

嵌入结构可以很好地解决:

class SomeClass
{
  // class var classVariable: Int = 0
  // "Class variables not yet supported." Weird.

  // Workaround:
  private struct SubStruct { static var staticVariable: Int = 0 }

  class var workaroundClassVariable: Int
  {
    get { return SubStruct.staticVariable }
    set { SubStruct.staticVariable = newValue }
  }
}

然后,可以将SomeClass.workaroundClassVariable计算类型属性用作存储类型属性。


1
为我工作-除非我必须放弃“ public”,否则XCode 6.0不喜欢我在内部类中声明public类。
Ali Beadle 2014年

除xcode不允许在通用类型中使用嵌套类型外,它的工作原理非常好……因此,如果您有一个通用类,则看起来只有绝望的希望,因为只有计算属性才是可能的。
BenMQ 2015年

19

似乎可以在文件范围内声明具有静态存储持续时间的变量(如在C中):

var sharedInstance: SplitViewController? = nil

class SplitViewController: UISplitViewController {
    ....
    func initialization() {
        sharedInstance = self
    }
}

mmmh,为什么不这样,但是在文件范围内定义var长时间使用不会造成内存泄漏?
文森特·萨卢佐

@VincentSaluzzo与Swift之前的操作没有什么不同:将唯一的实例存储在静态变量中。除了可以在进程中生存的单个实例之外,这里没有其他任何泄漏。
Nikolai Ruhe 2014年

我在同班同学的操场上尝试过。它不起作用,因为初始化“静态”变量时尚未声明该类。我没有在Xcode项目中尝试过它(我想它一定在那里工作了吗?)。因此,我可能需要像在为类指定协议时一如既往地弄清楚“类转发声明”。
kawingkelvin 2014年

2
请注意,在Xcode 6.0中,即使有两个文件作用域变量,它们也不能使用相同的名称private
nschum 2014年

@NikolayTsenkov确实如此。
Nikolai Ruhe

14

我的首选方法是只在类外部使用私有文件范围var,然后实现类/静态getter和setter:

private var _classVar: Int = 0;

class SomeClass
{
    public class var classVar: Int
    {
        get { return _classVar }
        set { _classVar = newValue }
    }
}

5

从Swift 1.2(适用于Xcode 6.3b1及更高版本)开始,static支持类属性和方法。

class SomeClass
{
    static var someVariable: Int = 0
}

1
如果它们只是不赞成使用class变量,还是有区别(以前static用于结构,class用于类),您是否注意到了?
克里斯·康诺佛

@chrisco发行说明声明这static是的别名class final
Andreas Ley 2015年


4

一个在文件范围上与var足够相似但更可定制且更接近单例的解决方案是使用支持静态var作为类属性的结构

struct PersonSharedData {
    static var backstore = ""
    var data: String {
    get { return PersonSharedData.backstore }
    set { PersonSharedData.backstore = newValue }
    }
}

class Person {
    var shared=PersonSharedData() //<< pseudo class var
    var family: String {
        get { return shared.data }
        set { shared.data=newValue }
    }
    var firstname = ""
    var lastname = ""
    var sexe: Sexe = .Unknown
}

2

好的,使用尼古拉的解决方案来完成这项工作。我将我的更改发布在此线程中以供参考

var instance: SplitViewController? = nil

class SplitViewController: UISplitViewController {

    class func sharedInstance() -> SplitViewController? {
        return instance;
    }

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.initialization()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder);
        self.initialization()
    }

    func initialization() {
        instance = self
    }
}

例如,在我的appDelegate中,我可以像这样访问此静态方法

SplitViewController.sharedInstance()!.presentsWithGesture = false

我只是很好奇,但是变量“ instance”不是全局变量吗?这意味着如果您有另一个单例类,则变量“实例”将被覆盖,对吗?
拉斐尔2014年

1

错误中的措词在很大程度上暗示了这将是将来的语言功能。

您可能要临时求助于在Application Delegate中声明属性变量,然后从那里检索它。不理想,绝对是反模式,但是会UISplitViewController在需要时为您提供一个集中的位置来检索该模式。


否,因为在我的情况下,从情节提要中唤醒时,SplitViewController是在运行时初始化的,所以我无法从我的应用程序代表处直接访问此视图控制器
Vincent Saluzzo 2014年

1

您必须将类变量包装在内部struct变量中

class Store{
    var name:String
    var address:String
    var lat:Int
    var long:Int
    init(name:String, address:String, lat:Int, long:Int){
        self.name = name
        self.address = address
        self.lat = lat
        self.long=long
    }

    private struct FACTORY_INITIALIZED_FLAG { static var initialized: Bool = false
       static var  myStoreList:[Store]?
        static func getMyStoreList()->[Store]{
            if !initialized{
                println("INITIALIZING")
                myStoreList = [
                    Store(name: "Walmart", address: "abcd", lat: 10, long: 20),
                    Store(name: "JCPenny", address: "kjfnv", lat: 23, long: 34)
                ]
                initialized = true
            }
                return myStoreList!
    }
    }
}


var a = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()

var b = Store.FACTORY_INITIALIZED_FLAG.getMyStoreList()

// only prints INITIALIZING once

0

试试这个:

class var instance: SplitViewController {
    return nil
}

0

在Swift中,它称为类型属性

您可以使用static关键字定义类型属性。对于类类型的计算类型属性,可以改用class关键字来允许子类覆盖超类的实现。下面的示例显示了存储和计算的类型属性的语法:

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}
class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

在下面的链接中阅读更多内容,

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID254

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.