Search Your Question

Showing posts with label Angel Broking. Show all posts
Showing posts with label Angel Broking. 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!