IOS development Swift Structs vs. Classes
Class Example
import foundationclass ClassSuperhero{var name : Stringvar universe : Stringinit(name: String , universe:String){self.name = nameself.universe = universe}}//let hero = ClassSuperhero(name:"Iron Man" , universe :"Marvel")
swift compiler doesn’t let classes, structs, and enums with the same name.
Struct Example
import Foundationstruct StructSuperhero{var name : Stringvar universe : Stringfunc revereseName1()->String{// self.name.reversed() : this will return a collectionnot a stringreturn String(self.name.reversed())}//this function will do goodfunc revereseName2(){self.name = self.name.reversed()//this will give us an error because we are trying tochange on of the struct's properties.//so we should use the mutating keyword}mutating func revereseName2(){self.name = self.name.reversed()}}
even though we have no initializers here we don’t get an error here unlike classes because in structs we actually get a free initializer.
Main
import Foundationvar hero = ClassSuperHero(name:"Iron Man" , universe :"Marvel")var anotherMarvelHero = hero // we can simply make a copyof instances of classesanotherMarvelHero.name = "Hulk"print(hero.name)print(anotherMarvelHero.name)//these two lines will both print "Hulk". because classesare reference types unlike structs it means now we have torefrences to the same object.avengers[0].name = "Thor"print(hero.name) //prints "Thor"print(anotherMarvelHero.name) //prints "Thor"print(avengers[0].name) //prints "Thor"
this can be fixed by using structs.
var hero = StructSuperHero(name:"Iron Man" , universe :"Marvel")var anotherMarvelHero = heroanotherMarvelHero.name = "Hulk"var avengers = [hero , anotherMarvelHero]print(hero.name) //prints "Iron Man"print(anotherMarvelHero.name) //prints "Hulk"//changing the anotherHero's name doesnt effect the hero'sname because structs are value typesavengers[0].name = "Thor"print(hero.name) //prints "Thor"print(anotherMarvelHero.name) //prints "Hulk"print(avengers[0].name) //prints "Thor"
try using structs as much as possible instead of classes to guard messing the code.
let constantHero = ClassSuperHero(name:"Iron Man" ,universe : "Marvel")
constants get a value assigned only once and they cant be changed. But the following line of code doesn’t get any error.
constantHero.name = "Cat Woman"
because the name and universe are declared as var in the ClassSuperHero. the only problem occurs when we try to assign constantHero to anothr class like:
hero = ClassSuperHero()
This is what the let prevents us from doing! but that’s not what we want. the only reason why we use constants is to prevent the accidental change of our object and this can also be fixed by using structs!
let constantHero = StructSuperHero(name:"Iron Man" ,universe : "Marvel")constantHero.name = "Cat Woman" // this will result in anerror!
There is just one thing that structs cant do we have to be aware of and that’s the can’t subclass, we don’t get inheritance from structs. If we need inheritance we have to use class! When using swift with objective-c we cant use structs because structs in objective-c is so different from structs in swift!
Struct StructHero : NSObject{}// this will give me anerror!
Conclusion
- A Struct is a “value type” that means it’s copied whenever it’s used.
- A class is a “reference type” that means the object it’s not copied and the reference is copied and when we change it we are changing the same underlying object!
Structs :
- Simpler
- Faster ( because they are stored in stack rather than heap)
- Deep copies
- True immutability
- No memory leaks
- Thread safe
Classes :
- Has inheritance
- Works with objective-C code //lots of API’s for iPhone is still in objective-c
Apple’s last words on this subject is that :
You should use structs by default whenever you want to create a
custom object and only turn it into a class when you find out that you
actually need inheritance or you need to work with objective-c code!
Strat with structs and only go up if needed just like access levels!