Dauris Little
  • About
  • Blogging Lyf
  • Contact
  • Portfolio
“Never be limited by other people’s limited imaginations.” – Dr. Mae Jamison

Swift Has Tuple

Monday, 31 May 2021 by Dauris

It is a very common use case where we want to return two values from a method, which can be either of the same data types or can be of different data types. Typically within this case, we would either create various local variables if the method is of the same class and set those variables from the method and consume them in the place where needed or we could create a struct and return that struct object from the method.

This approach works fine but is it worth defining a new struct every time when we return value(s) from a method. As great as that may sound consider this then if you have several methods which also return value(s) but each method returns the value(s) of different data types. I suppose in said case you could create a separate struct for each of the methods but it isn’t practical and comes on just terrible programming.

Got a Solution?

As the title of this article should have implied Swift has a type called Tuple which is used to group various values in a single compound value. Storing or returning two values of the same or different data types is child play for a tuple. here can or cannot be any relation between both the values.

Using Tuple

It is initialized in two ways:

  • unnamed variables
    • where the names are not defined within the tuple and use their position to access it
var tuple = ("football", "basketball")

print(tuple.0)
print(tuple.1)
  • named variables
    • where the names are defined within the tuple and use the names that were defined for them
var tuple = (atk : 2500, def : 2100)

print(tuple.atk)
print(tuple.def)
functional programmingiOSiOS Developmentswiftswift programming
Read more
  • Published in iOS, Programming Languages, Swift
No Comments

“Structs vs Classes” and using them

Saturday, 01 May 2021 by Dauris

This is because it plays a significant role in choosing the right abstraction mechanism keeping both performance and modeling in mind. As you can only imagine this topic is simply the tip of the iceberg. Many advanced concepts and questions of classes and structs in swift. With that being, I have broken this topic into two parts. 

Structs & Classes — What are they?

Consider them like templates or guidebook that contains variables and methods used to all object of the said kind. In short, they assist in keeping the code organized for future maintenance and reusability.

Class features over structs

  • Inheritance
    • inherit the characteristics of another class
  • Type-casting
    • checks and interprets the type of a class instance at runtime 
  • Deinitializers
    • enable an instance of a class to free up any resources it has assigned
  • Reference Count
    • allows multiple references to a class instance 

Value & reference types

  • Value types
    • each instance keeps an independent copy of its data
      • example: structs, enums, or tuples
    • changing one instance will have no effect on the other
  • reference type
    • Instances share a single copy of the data. 
    • changing data in one instance will change the data for all instance pointing to the same instance 
      • example: classes

Deciding to class or struct 

when deciding on a new model we, as developers,  should carefully contemplate the use cases of the model. With that stated, you should decide between structs and classes.

using classes:

class Network {
   var url:String
   init(url:String) {
      self.url = url
   }
}

var req = Network(url: "https://daurislittle.com")
var newReq = req
newReq.url = "https://facebook.com"

if req === newReq {
   print(req.url)
   print(newReq.url)
}
  • comparing instance identity with “===” makes sense
  • Creating a shared and mutable state
    •  if your intent is to share the state among the threads and variables use classes

using structs:

You will note the code below compare the value of the Network URLs and not the memory addresses.

struct Network {
   var url:String
}

extension Network:Equatable{}

let req = Network(url: "https://daurislittle.com")
let newReq = Network(url: "https://facebook.com")

if req == newReq {
   print("Both the request contains the same address")
}
  • comparing instance data with “==” makes sense
    • data needs to be compared and the memory locations of these data are not important

Now you can see that both the requests have different URLs as each request have a different copy of the URLs

struct Network { 
   var url:String 
} 

extension Network:Equatable{} 

var req = Network(url: "https://daurislittle.com") 
var newReq = req

newReq.url = "https://facebook.com"

print(req.url) //https://daurislittle.com
print(newReq.url) //https://facebook.com

Now you can see that both the requests have different URLs as each request have a different copy of the URLs

  • Data can be used in code across multiple threads
    • when passing and copying value types in a multi-threaded environment we can be sure that each context will have a separate unique copy which will not impact the others
      • This helps avoid a lot of unintentional bugs

Memory Allocation w/structs and classes 

structs are allocated in the stack memory. References of the class objects can be created on the stack but all the properties of the class’s object will be kept in the heap

Reference counting 

As stated above classes support heap allocations they need to maintain reference counts for allocation and deallocating objects. On the other hand, structs do not need reference counting. However, if structs contain references then they would incur twice the number of reference counting overhead as compared to a class.

Method Dispatching

Classes use method dispatch but if a class is marked as “final“, the compiler will use static dispatch. Stucts uses “static” dispatch.

Memberwise initializers

Memberwise initializers are those initializers which the compiler generates automatically for structs. We can initialize a struct’s object using these initializers even though we have not provided any custom initializers.

enum RequestType {
   case get, post, delete
}

struct Network {
   val url:String
   var type:RequestType

   //Memberwise init generated by the compiler
}

var req = Network(url:"https://daurislittle.com", type: .get)

Note: order arguments in these initializers are decided by the order of the declared properties in struct.

However, as a developer we can write any custom initializer, the compiler now though will not generate the memberwise initializer. You can use both generated memberwise and custom initializers, just need to add the custom initializer within the extension of the struct.

enum RequestType { 
   case get, post, delete 
} 

struct Network { 
   val url:String 
   var type:RequestType //Memberwise init generated by the compiler 
} 

extension Network {
   initi(URL:String) {
      self = Network.init(url: url, type: .get)
   }
}

var req = Network.init(url:"https://daurislittle.com")

Keyword “mutating” and when to use it

When changing the property of any struct, using the keyword “mutating” before the “func” keyword when defining a method. This is because the self parameter that’s implicitly passed into every method is immutable by default.

extension Network {
   mutating func updateUrl(url:String) {
      self.url = url
   }
}
//self is passed as a var

The “mutating” keyword allows the compiler to decide which methods can’t be called on let constants. If we try to call a mutating method on a “let” constants. If we try to call the mutating method on a let variable, the compiler shows an error. 

iOSMobile Developmentswiftswift 4swift 5swift programming
Read more
  • Published in blog, iOS, Programming Languages, Swift
No Comments

Using let or var within Swift

Saturday, 09 January 2021 by Dauris

I know I know I know before you say anything I understand this statement is probably ridiculous. However, this topic could aid someone or more likely open the floor to discuss concepts in general so without hesitation, we will dive into it.

let and var so what are they and their differences

 As you probably already know both let and var are for creating variables within Swift. Now with let it helps create an immutable variable(s) so consider it a constant but var is used for creating a mutable variable(s). Nonetheless, a variable created by either of them holds a reference or a value. 

The difference between the two is that when a developer creates a constant with let the value must be assigned before you can use it. While when you declare a variable with var it can be used before or after an assignment or never use it as well as reassigning it on the fly.

Mutate function parms

function parameters are constants by default. Trying to change their value within the function body results in a compile-time error.

func pokedex(for name: String) { 
   name = "charmander" 
} 

pokedex(for: "mex")

//Line 2 cannot assign to value is let constant

Test: Build & Compile

struct Pokemon { 
   var name: String 
   let weakness: String 
} 

let trainerAPokemon = Pokemon(name: "Charmander", weakness: "water") 
trainerAPokemon .name = "Bulbasaur" 
trainerAPokemon .weakness = "fire" 

var trainerBPokemon = Pokemon(name: "Pikachu", weakness: "rock") 
trainerBPokemon.name = "Squirtle" 
trainerBPokemon.weakness = "electricity"

In the example above we are using a struct. Whenever you try to muate them they get copied with mutation applied to them and reassigned back.

Now let’s review everything within the block. The let variable within the struct cant is mutated as it would mean you are mutating the value of an immutable variable. However, our friend the var variable within the struct can be mutated. 

  • Line 7
    • cannot assign to the property trainerAPokemon because it is a let constant
  • Line 8 & 12
    • cannot assign to the property weakness because it is a let constant

Test: Build & Compile

class Pokedex {
   var name: Int
   let num: String

   init(name: String, num: Int) {
      self.name = name
      self.num = num
   }
}

let trainerA = Pokedex(name: "Lucario", num: 448)
trainerA.name = "Squirtle"
trainerA.num = 7

var trainerB = Pokedex(name: "Bulbasaur", num: 1)
trainerB.name = "Gengar"
trainerB.num = 94

In the example above we are now using a classes. When attempting to mutate them, the object stored elsewhere in memory gets mutated while the reference to it remains the same.

You can modify a class’s members whether or not the variable referencing it is mutable

  • Line 13 & 17
    • cannot assign to property num because it is a let constant

 

 

 

letprogramming w/ swiftswiftswift 4swift 5swift programmingvarvar vs let
Read more
  • Published in blog, iOS, Programming Languages, Swift
No Comments

All rights reserved. 

TOP
This site uses tracking cookies to personalize content and ads. AcceptLearn More