对我来说,我使用static 或class 方法来控制类级别的属性,或者如果我必须返回特定class 或struct 的自定义实例。例如考虑我在struct下面。
struct Person {
let firstName: String
let lastName: String
}
现在,如果我正在编写一些测试用例,我需要在我的许多测试类中使用特定名称 John 初始化 Person 的实例,我可以创建一个帮助程序 static 方法。
extension Person {
static func john() -> Person {
return Person(firstName: "John", lastName: "Appleseed")
}
}
let john = Person.john() // I could also create a static property instead, but it's a matter of personal choice and situation.
在上述情况下,我也可以将 john 设为全局函数,但对我来说,它会非常模糊且不可读。
我能想到的另一个我更喜欢静态方法的地方是返回 enum 的案例计数。
enum Mood {
case happy
case angry
case lazy
case high
static func count() -> Int {
return 4
}
}
有些地方我使用全局函数。我使用全局函数进行日志记录。
func log(screenEvent name: String) {
let tracker = GAI.sharedInstance().defaultTracker
tracker.set(kGAIScreenName, value: screenName)
let builder = GAIDictionaryBuilder.createScreenView()
tracker.send(builder.build() as [NSObject : AnyObject])
}
在内部,该方法使用sharedInstance,创建一个全局方法使其在项目中的任何地方都可以轻松访问,就像在控制台中记录输出的print函数一样,但这是在一些自定义服务中登录。
我通常在我的项目中包含的其他一些全局函数是 GCD 助手。
func delay(delay:Double, closure: dispatch_block_t) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
func backgroundTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), closure)
}
func mainThreadTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), closure)
}
这些函数不需要关于类的任何信息,因此将它们设为全局而不是将它们包装在类中是有意义的。
关于instance 方法,正如@Duncan C 所回答的那样,当您想要保持状态时,它们会在实例上调用。下面的示例显示了静态方法和实例方法的用法。
enum TapType {
case water
case beer
}
struct Tap {
let tapType: TapType
//static method
static func unlimitedBeer() -> Tap {
let beer = Tap(tapType: .beer)
beer.turnOn(forDuration: Float.greatestFiniteMagnitude)
return beer
}
//instance method: will do operation on a particular instance of `Tap`.
func turnOn(forDuration duration: Float) {
//implementation
}
}
let unlimitedBeer = Tap.unlimitedBeer()
您始终可以使用convenience 初始化程序来初始化具有自定义行为的对象,但同样,这是一个选择问题。在上面的例子中,我想不出任何convenience 初始化器可以给我无限量的啤酒。