创建预设结构的正确方法是什么?

时间:2015-11-10 19:21:32

标签: swift

在Swift类中,我们可以使用class function来创建预设实例。像下面的日历示例:

let calender = NSCalendar.currentCalendar()

这将具有与此类似的模式:

class SomeClass {

    var attribute : String

    init(value:String) {
        attribute = value
    }

    class func testClass() -> SomeClass {
        return SomeClass(value: "test")
    }
}

let test = SomeClass.testClass()

但显然没有结构中的类函数。 Xcode建议使用static代替。这非常接近单身模式。

struct SomeStruct {

    var attribute : String

    init(value:String) {
        attribute = value
    }
    static var testStruct = SomeStruct(value: "test")
}

单身人士模式

class Singleton {

    static let shared = Singleton()

    private init() {

    }
}

因为结构是值类型,所以这是一个使用预设值初始化结构的好方法。如果不行,那么正确的方法是什么?

1 个答案:

答案 0 :(得分:2)

结构类型的等效class funcstatic func

static func testStruct() -> SomeStruct {
    return SomeStruct(value: "foo")
}

和静态属性(“singleton-pattern”)的工作方式相同 同时使用类和结构类型:

static let singleStruct = SomeStruct(value: "foo")

testStruct()为每次调用创建一个值,而singleStruct 创建一次值(在第一次调用时)。

在大多数情况下,因为结构不会产生任何影响 价值类型。如果创建静态属性有优势 价值是“昂贵的”。另外,正如@Lance在评论中注意到的那样, Apple经常使用此模式,例如CGRect.zero

但是,如果struct具有属性,则会有所不同 是引用类型(或指向非托管内存的指针)。这是一个例子:

class MyClass {
    var attribute : String
    init(value : String) {
        attribute = value
    }
}

struct SomeStruct {

    var ptr : MyClass

    init(value : String) {
        ptr = MyClass(value: value)
    }
    static func testStruct() -> SomeStruct {
        return SomeStruct(value: "foo")
    }

    static let singleStruct = SomeStruct(value: "foo")
}

使用静态功能:

let test1 = SomeStruct.testStruct()
print(test1.ptr.attribute) // foo

let test2 = SomeStruct.testStruct()
test2.ptr.attribute = "bar"

print(test1.ptr.attribute) // foo

此处test1test2是单独的值,我们得到预期的值 输出

使用静态属性:

let test1 = SomeStruct.singleStruct
print(test1.ptr.attribute) // foo

let test2 = SomeStruct.singleStruct
test2.ptr.attribute = "bar"

print(test1.ptr.attribute) // bar  <--- What?

此处,test1test2设置为从中返回的相同值 静态属性。更改test2.ptr 不会改变 test2, 导致test1.ptr.attribute

的输出有些出乎意料

请参阅Friday Q&A 2015-04-17: Let's Build Swift.Array,了解有关如何解决此问题的有趣文章。

顺便说一下,static也可以与类类型一起使用,staticclass final的快捷方式:无法覆盖的类型方法 在子类中。由于它没有继承结构类型 感觉结构类型的类型方法被写为static