Static VS Class as Class Variable/Method (Swift)

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



Leave a reply



Submit