Static vs class functions/variables in Swift classes?
static
and class
both associate a method with a class, rather than an instance of a class. The difference is that subclasses can override class
methods; they cannot override static
methods.
class
properties will theoretically function in the same way (subclasses can override them), but they're not possible in Swift yet.
Can you explain me the difference static and class in swift?
The difference between a function defined as static func
and another one defined as class func
is that static
is for functions of structures and enumerations, and class
is mainly for functions of protocols and classes.
Class functions can also be overridden by subclasses. For example:
class Animal{
class func generateAnimalSound(){
print("Some Animal Sound")
}
static func isAnimal() -> Bool{
return true
}
}
class Cat: Animal{
override class func generateAnimalSound(){
print("Meow!")
}
}
var someAnimal = Animal.generateAnimalSound() // prints "Some Animal Sound"
var cat = Cat.generateAnimalSound() // prints "Meow!"
However, if you try to override the static member function isAnimal()
, this will result in an error:
Cannot override static method
That's obviously because static methods cannot be overridden by subclasses. You should read the documentation provided both by Apple and other StackOverflow related questions:
- What is the difference between static func and class func in Swift?
static vs class as class variable/method (Swift)
The Swift Programming Language (Swift 3.1) - Methods
static vs class as class variable/method (Swift)
From the Xcode 3 beta 3 release notes:
“static” methods and properties are now allowed in classes (as an
alias for “class final”).
So in Swift 1.2, hi()
defined as
class foo {
static func hi() {
println("hi")
}
}
is a type method (i.e. a method that is called on the type itself)
which also is final (i.e. cannot be overridden in a subclass).
What is the difference between static func and final class func in swift
Just because a final
class function can't be overridden doesn't mean it's statically dispatched. A final class function be override a superclass non-final class function. Such a method call must be dynamically dispatched.
static
is merely an alias for final class
. They behave the same:
class C1 { class func foo() {} }
class C2: C1 { override final class func foo() {} }
class C3: C1 { override static func foo() {} }
static functions vs normal class function
Under the hood a static function differs from an instance function only in how it takes its implicit parameters: instance functions take one implicit parameter for self
, while static functions take no implicit parameters for anything.
As far as the code for the function is concerned, there is no penalty for a function being static or non-static. Same goes for performance: static functions are simplest lightweight "packages" of executable code; calling them carries no additional costs.
Your particular implementation, however, may benefit from storing activityIndicator
in a variable to avoid re-creating it in each static call. Moreover, this would make it easier for you to remove the activity indicator from superview once the activity has finished. If you would like to use a single activityIndicator
, you could keep your function static, and add a class variable for activityIndicator
. Otherwise, you should make multiple instances of ActivityIndicator
class, each having its own activityIndicator
instance variable. In this case, startActivityIndicator
should become an instance method as well.
What is the difference between static func and class func in Swift?
Is it simply that static is for static functions of structs and enums, and class for classes and protocols?
That's the main difference. Some other differences are that class functions are dynamically dispatched and can be overridden by subclasses.
Protocols use the class keyword, but it doesn't exclude structs from implementing the protocol, they just use static instead. Class was chosen for protocols so there wouldn't have to be a third keyword to represent static or class.
From Chris Lattner on this topic:
We considered unifying the syntax (e.g. using "type" as the keyword), but that doesn't actually simply things. The keywords "class" and "static" are good for familiarity and are quite descriptive (once you understand how + methods work), and open the door for potentially adding truly static methods to classes. The primary weirdness of this model is that protocols have to pick a keyword (and we chose "class"), but on balance it is the right tradeoff.
And here's a snippet that shows some of the override behavior of class functions:
class MyClass {
class func myFunc() {
println("myClass")
}
}
class MyOtherClass: MyClass {
override class func myFunc() {
println("myOtherClass")
}
}
var x: MyClass = MyOtherClass()
x.dynamicType.myFunc() //myOtherClass
x = MyClass()
x.dynamicType.myFunc() //myClass
Confused by the usage of a class or a struct as container for static variables (Swift)
What you're doing is clumping global constants into a namespace.
Is there a special Container Object in Swift designed for such purposes?
Yes, a caseless enum is the conventional way to do this, as it is the most lightweight and cannot be accidentally instantiated; it is "pure" namespace.
If you watch some Apple videos you'll see that's how they do it. Personally I used to recommend a struct but I've switched to using enums for the reason given.
When to use static constant and variable in Swift?
When you define a static var/let into a class (or struct), that information will be shared among all the instances (or values).
Sharing information
class Animal {
static var nums = 0
init() {
Animal.nums += 1
}
}
let dog = Animal()
Animal.nums // 1
let cat = Animal()
Animal.nums // 2
As you can see here, I created 2 separate instances of Animal
but both do share the same static variable nums
.
Singleton
Often a static constant is used to adopt the Singleton pattern. In this case we want no more than 1 instance of a class to be allocated.
To do that we save the reference to the shared instance inside a constant and we do hide the initializer.
class Singleton {
static let sharedInstance = Singleton()
private init() { }
func doSomething() { }
}
Now when we need the Singleton
instance we write
Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()
This approach does allow us to use always the same instance, even in different points of the app.
Related Topics
Following in App Purchase, App Crashing on Startup. Productidentifier=Nil
Set<Nsobject>' Does Not Have a Member Named 'Anyobject." - Xcode 6.3
How to Programmatically Get iOS's Alphanumeric Version String
Detect If iOS App Is Downloaded from Apple's Testflight
Uibutton with Single Press and Long Press Events Swift
Setting Up a Plist to Store Application Data (Not Settings) for an iPhone Game
Why Is Audio Coming Up Garbled When Using Avassetreader with Audio Queue
Get Cellid, Mcc, Mnc, Lac, Signal Strength, Quality and Network in iOS 8.3
Sending Latitude and Longitude to Server When App Is in Background
Detect Hotspot Enabling in iOS with Private API'S
Ios: Usage of Self and Underscore(_) with Variable
Uibutton with Single Press and Long Press Events Swift
Uiscrollview with iOS Auto Layout Constraints: Wrong Size for Subviews
Adding Swift Files to Test Target Not Fixing Unit Tests
How to Determine If a User Has an iOS App Installed
How to Share My Current Location to Uiactivityviewcontroller