Search Your Question

Showing posts with label Swift. Show all posts
Showing posts with label Swift. Show all posts

What is capture and capture list in closure?

Ans :

According to apple document :

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages. 

Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables. Swift handles all of the memory management of capturing for you.

Closure is reference type

Capturelist is used to stop memory leakage.

Code for Example of memory leakage :


class Increment {
    var number = 0

     deinit {
        print(#function)
    }
    
    lazy var incrementNumber: (Int) -> () = { value in
        self.number += value
        print(self.number)
    }
}

 do {
  let increment = Increment()

  increment.incrementNumber(3
 }


This will cause memory leak, the closure refers back to the object itself, it refers to self in order to increment the number, and that will create a reference cycle:

We have an object and the object has a stored property that refers to a closure.
That closure refers back to self (means Increment instance)

In above example, deinit should be called. But it never due to retain cycle created.

To Stop memory leakage we use capture list :

1. [unowned self]
2. [weak self]
3. [strong self] - Default

1.

lazy var incrementNumber: (Int) -> () = { [unowned self] value in
        self.number += value
        print(self.number)
    }

If I use [unowned self] there here less chance to crash. But if we use
let increment = Increment().incrementNumber(3)
then there will be more chance to be crashed. We can not immediately call incrementNumber method after object instantiated. Because when the stored property has returned, the object (increment instance) can be deallocated, nothing else is referring to it.

2.

 let’s change [unowned self] to [weak self], that means that everywhere that self is accessed, we treat it as a weak property. While using weak, we should use optional self? to access property.

When the stored property has returned, if the object be deallocated, mean self is nil, then the number will not be incremented. This code will make it easy to handle if self is nil

So when no clue to what to use, we should use [weak self] as capture list.





What is Generics in Swift? Write a program to make and use generics.

Ans :

Apple doc says: Generic code enables you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication by using generics in most cases.

Code for Example :


 let intArray = [1,2,3,4,5] // type int
 let stringArray = [“abhi”, “iOS”] // type string



If we want to print all values, we have to make 2 functions accepting integer array or string array.
But using Generic, we can make 1 method accepting generic type.



 func printAnyArray<T>(arr:[T]) {
       arr.map { print($0) }

 }


 <T> after the function name represents a generic function. A generic function can work with whatever type. We can put whatever instead of T. T is placeholder type. We can use for dictionary like Dictionary<key,value> and for array like Array<element> .

Generic function with parameter type : 


//Declare
func anotherMethod<T, U> (first: T, second: U) { print("first one called")}
func anotherMethod<T> (first: T, second: T) { print("second one called")}
//Call
anotherMethod(first: 123, second: "456"// T - Int, U - String
anotherMethod(first: 123, second: 456// T - Int




In above methods, we use different placeholder type in method1 and same placeholder type in method2. If out passing parameter types are different then 2nd method will be called, and if same then 1st method will be called.

Generic function with type constraints :


func middleVal<T>(array: [T]) -> T? {
  guard !array.isEmpty else { return nil }
  return array.sorted()[(array.count - 1) / 2]
}

   

Sometimes, we require specific types only i.e type which confirm comparable protocol


func middleVal<T: Comparable>(array: [T]) -> T? {
  guard !array.isEmpty else { return nil }
  return array.sorted()[(array.count - 1) / 2]
}

    

Above method will only accepts. int, float, double.


If you have any comment, question, or recommendation, feel free to post them in the comment section below!  

Json serialization and deserialization

Ans :  


JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
When transmitting data or storing them in a file, the data are required to be byte strings, but complex objects are seldom in this format. Serialization can convert these complex objects into byte strings for such use. After the byte strings are transmitted, the receiver will have to recover the original object from the byte string. This is known as deserialization.

import UIKit

var str = "Hello, playground"

// Starting decode -> json to class or object
// ------------- De-Serialization ----------------

let singleDict = """
{
    "foodName" : "Banana"
    "calories" : 100
}
""".data(using: .utf8)

class Food: Codable {
    
    let foodname : String
    let calories : Int
    
    init(foodname: String, calories: Int) {
        self.foodname = foodname
        self.calories = calories
    }
}

let jsonDecoder = JSONDecoder()
do {
    let foodResult = try jsonDecoder.decode(Food.self, from: singleDict!)
    print(foodResult.foodname)
} catch {
    print("failed to decode \(error.localizedDescription)")
}

// Starting encode -> class or object to json
// ------------- Serialization ----------------

let apple = Food(foodname: "apple", calories: 80)
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
do {
    let jsonData = try jsonEncoder.encode(apple)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
} catch {
    

}

What is Codable?
Codable is a type alias for the Encodable and Decodable protocols. When you use Codable as a type or a generic constraint, it matches any type that conforms to both protocols.

Before Swift 4, You’d have to serialize the JSON yourself with JSONSerialization, and then typecast every property of the JSON to the right Swift type. We have to do manually map data with struct (Model) properties.
If we are using Codable, then we don't required to map response data with struct property manually. If response's name is different then we can use CodingKey

struct User:Codable 
{
    var firstName: String
    var lastName: String
    var country: String

    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
        case country
    }
}


If you have any comments, questions, or recommendations, feel free to post them in the comment section below!

What is subscript?

Ans : 

Subscripts are used to access information from a collection, sequence and a list in Classes, Structures and Enumerations without using a method.

These subscripts are used to store and retrieve the values with the help of index without the use of separate method.

To access elements via subscripts write one or more values between square brackets after the instance name.

For example: Array elements are accessed with the help of someArray[index] and its subsequent member elements in a Dictionary instance can be accessed as someDicitonary[key].

Code :

In coding, subscript is same as computed property.



 class monthsInYear {
 private var months = [“Jan”, “Feb”, “Mar”, “Apr”, “May”, “Jun”, “Jul”, "Aug",  "Sep" , "Oct", "Nov" , "Dec"
 subscript(index: Int) -> String {

 get {
       return months[index] // getter is mandatory
  }
 set(newValue) {
       self.months[index] = newValue // setter is optional
     }
   }
 }
 var p = monthsInYear()
 print(p[0]) // prints Jan
 p[0] = “Jan”
 print(p[0]) // prints Jan



If you have any comment, question, or recommendation, feel free to post them in the comment section below!

Difference between KVO and KVC and Delegate

Ans : There is no way to find any differences between KVC and KVO. Both are different things.

1. KVC - Key Value Coding

We can get and set value of class property using string.

Code for example :

import UIKit

class Employee : NSObject {
    @objc var name = String()
    @objc var age = 0
    @objc var assets = ["ID Card", "Macbook"]

}

We should make sure that Employee inherits from NSObject because it confirms protocol named NSKeyValueCodiing.

We also make sure that @objc should be added as it is objective c runtime for making those properties available for coding. emp.setValue("Manna", forKeyPath: #keyPath(<#T##@objc property sequence#>))

Using KVC,
let emp = Employee()
emp.setValue("Manan", forKey: "name")

Here, we set value of name property using string "name". Here there is chance to misspell property name.

Another way,

emp.setValue("Manna", forKeyPath: #keyPath(Employee.name))

Benefit of this way,  There is no any chance to misspell as it only accepts valid key path other wise it gives compile time error.

Another way,

emp.setValuesForKeys([
                        "name" : "Manan",
                        "age"  : 29

                ])

What will happened, if we have some private properties in class. They are not accessible directly using their value. We have to make extension of class to use their values.
or

@objc private var name = String()

emp.setValue("Manan", forKey: "name")
emp.value(forKey: "name")

We can access private properties as above using KVC. emp.name will give compile time error as name is private,  but using KVC it is possible to access.

We can access array and add item in this array,

let mutableArray = emp.mutableArrayValue(forKeyPath: #keyPath(Employee.assets))
mutableArray.add("Laptop Bag")


2. KVO - Key value observer

When we want to do something when property values changes, we can use KVO concept. We can observer property and on value changed we can take action.

For that,
A special method named observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) should be implemented to the observing class.


self.child1.addObserver(self, forKeyPath: "name",  optional: [.new, .old], context: child1context]


There are some parameters :

  • addObserver:  This is the observing class, usually the self object. 
  • forKeyPath: I guess you can understand what’s this for. It is the string you used as a key or a key path and matches to the property you want to observe. Note that you specify here either a single key, or a key path. 
  • options: an array of NSKeyValueObservingOptions values. 
  • context: This is a pointer that can be used as a unique identifier for the change of the property we observe. Usually this is set to nil or NULL. We’ll see more about this later.
We have to implement  following observerValue method and it is mandatory to adopt KVO concept.




Sometimes, we don't want notification when some  property value changed. Then we do following :


Credit : HackerMoon

Know more about KVO : Click here

Difference between Delegate, Notification and KVO


Use a delegate if you want to talk to only one object. For example, a tableView has a delegate - only one object should be responsible for dealing with it.

Use notifications if you want to tell everyone that something has happened. For example in low memory situations, a notification is sent telling your app that there has been a memory warning. Because lots of objects in your app might want to lower their memory usage it's a notification.

I don't think KVO is a good idea at all and try not to use it but, if you want to find out if a property has changed you can listen for changes.

Meaning of ??, !!, !?, ?!

Ans : 

1. ?? is  Nil-Coalescing Operator. It is used to provide default value if value is nil.

let val = values["value1"] as? String ?? "default"

2. !!

i.e
struct StockFullData: Codable
{  
           var ok : Bool?  
           var sn : StockName?
}

struct StockName : Codable
{  
           let display_name : String?
}

Now Check :

print(s.sn?.display_name)      
print((s.sn?.display_name!))      
print((s.sn?.display_name!)!)      
 print((s.sn!.display_name!))

Output :

Optional("m")
Optional("m")
m
m

-> See third print, where we have used !! for extract value. I am not sure it is correct answer because it is like !)! .

3. !? : am finding answer or We can make custom operator using this .
4. ?! : am finding answer or We can make custom operator using this .

If you have any comment, question, or recommendation, feel free to post them in the comment section below!


What is Operator overloading?

Ans : 
Operator overloading is the practice of adding new operators and modifying existing ones to do different things. Operators are those little symbols like +*, and /, and Swift uses them in a variety of ways depending on context – a string plus another string equals a combined string, for example, whereas an integer plus another integer equals a summed integer.
To create a new operator, try adding this to a playground:
infix operator **
That’s the exponentiation operator, designed to raise one number to the power of another. Normally we’d use the pow() function for that job, but with operator overloading we can make ** work instead.
Now you need to tell Swift what to do when it sees that operator. For example, when we write something like 2 ** 4 what does that mean?
Syntax of making operator : 
func **(lhs: Double, rhs: Double) -> Double {
    return pow(lhs, rhs)
}
Use : 
let result = 2 ** 4
We can specify associativity and a precedence group also but it is very deep level.
If you have any comment, question, or recommendation, feel free to post them in the comment section below!

What is meaning of _ in Swift func ?

Ans : 


The _ is used to define that the parameter is not named
If you have multiple _ it states that you do not need to name the parameters in your function call
func myFunc(name:String, _ age:String){       }

myFunc(Milo", "I'm a really old wizard")
If you do not use the underscore you would use 
myFunc(Milo, age: "I'm a really old wizard")
The _ is not necessary in function calls. It is just used to indicate that something does not to have a name.



What is Enumeration in Swift?

Ans : 

What is enum?
An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
Enumerations offer an easy way to work with sets of related constants. An enumeration, or Enum, is a symbolic name for a set of values. Enumerations are treated as data types, and you can use them to create sets of constants for use with variables and properties.

When to use an enum?
Whenever a procedure accepts a limited set of variables, consider using an enumeration. Enumerations make for clearer and more readable code, particularly when meaningful names are used.

The benefits of using enumerations include:

  • Reduces errors caused by transposing or mistyping numbers. 
  • Makes it easy to change values in the future. 
  • Makes code easier to read, which means it is less likely that errors will creep into it. 
  • Ensures forward compatibility. With enumerations, your code is less likely to fail if in the future someone changes the values corresponding to the member names.



Some truths about protocol

Q1 : Can structure confirm protocol?
A1 : Yes

Q2 : Can enumeration confirm protocol?
A2 : Yes

Q3 : Can we declare variable in protocol?
A3 : Yes -> It must be var and it must be read-Only or readAndWrite . Property declaration is like following : 

protocol someprotocol {
     var gettable : Int { get }
      var setAndGettable : Int { get set }

Q4 : Can we add function in the enumeration?
A4 : Yes

Q5 : Can protocol has own init method?
A5 : Yes

Q6 : Can protocol inherit another protocol?
A6 : Yes
protocol someprotocol : anotherprotocol {

}

Q7: Can we make a class-specific protocol?
A7: You can limit protocol adoption to class types (and not structures or enumerations) by adding the AnyObject or class protocol to a protocol’s inheritance list.

protocol someprotocol : AnyObject, Someanotherprotocol {
}

Now someprotocol can only be confirmed by class type. No structure or enum type can confirm this protocol.

Q8. Can we declare an optional protocol method in swift?
A8. Yes. In that protocol name and optional methods should be followed by @objc due to it consider as objective c code.

@objc protocol someprotocol {
        @objc optional func somemethod()
        @objc optional var someName : String { get set }
}

or 

We can make protocol extension and provide default body to protocol method. So any class or struct confirms that protocol doesn't require implementing that method.

Q.9 Can protocol be fileprivate?

A9. Yes. Protocol can be fileprivate, private, public. Private and fileprivate protocol can be confirmed only within current file.

Q.10 Can we define property in extension?
A10. Swift doesn’t support stored properties inside the extension. Computed property is allowed in extension.

Q.11 Can we define property in protocol?
A.11 Property in protocol must have explicit { get } or { get set } specifier. 

protocol VoiceAssistant {
        var s : String // Not allowed
        var name: String {get} // Allowed
        var voice: String {get set} // Allowed

    }

Q.12 Can we declare same name property in protocol and its extension with different datatype?
A.12 Yes. Extension declared property must have valid getter method.

protocol VoiceAssistant {
   
    var name: String {get}
    var voice: String {get set}
}

extension VoiceAssistant {
    var name: Int {get { return 5}}

}

Q.13 Can we define body in method in protocol? How?
A.13 Yes.

protocol VoiceAssistant {
    func makeMessage()
}

extension VoiceAssistant {
    func makeMessage() {
        print("Default make message method")
    }

}