Search Your Question

Showing posts with label ARC. Show all posts
Showing posts with label ARC. Show all posts

Difference between assign and retain in iOS

In the context of memory management in programming, particularly in Objective-C (though less relevant in modern Swift), "assign" and "retain" are related to the property attributes used in the declaration of object properties.

  1. Assign:


    • In the context of Objective-C, the assign attribute is used for simple assignments and is often associated with primitive types or non-Objective-C objects.
    • When you declare a property with the assign attribute, you're saying that the property will just take the value assigned to it without affecting the reference counting of the object.

    • @property (assign) NSInteger someInteger;

    • For objects, assigning does not increase the retain count, so if the assigned object is deallocated elsewhere, you might end up with a dangling pointer.

  2. Retain:


    • The retain attribute, on the other hand, is used when you want to claim ownership of an object. It increases the retain count of the object, indicating that you want to keep a reference to it.
     
    @property (retain) NSString *name;


    • When using retain, it's your responsibility to release the object when you're done with it. This is crucial to avoid memory leaks.

    • [name release];

    • In modern Objective-C and Swift, Apple introduced Automatic Reference Counting (ARC), which essentially automates the reference counting process. In Swift, you generally use strong instead of retain, and the memory management is handled by the ARC.

In summary, the key difference is that assign is used for non-object types and doesn't affect the reference counting of objects, while retain (or strong in Swift) is used for objects, and it does increase the retain count, indicating ownership. With ARC in Swift, the need to manually specify assign or retain has diminished, as ARC takes care of many memory management tasks automatically.AI.


What is AutoReleasePool?

Ans : 

In simple word, it is pool contained objects that will be released in some time.

Object's retain and release is constant action on object. For that Retain() and Release() methods called in objective c to control memory flow. As iOS objects work on retain count concept, it tells retain counts and it will be released if it reaches to 0.

Sometimes, we can not continuously use Release() method to release object.

Code for example :

 -(NSString *)getCoolLabel {
    NSString *label = [[NSString alloc] initWithString:@"SwiftRocks"];
    [label release];
    return label;
 }

    

Here label has 2 retain count and after return it has 1 retain count. It will be in memory as we can not execute release after return label; statement.

So solution :
return [label autorelease];
It will not release label instantly, but it inserts label in pool, and in some time, when autorelease pool thread execute, it

Note : Instead of instantly reducing the retain count of an object, autorelease() adds the object to a pool of objects that need to be released sometime in the future, but not now. By default, the pool will release these objects at the end of the run loop of the thread being executed, which is more than enough time to cover all usages of getCoolLabel() without causing memory leaks.

Whatever code that takes much memory we can add in autoreleasepool block.
I.e

@autoreleasepool {
           NSString *contents = [self getFileContents:files[i]];
           NSString *emojified = [contents emojified];
           [self writeContents:contents toFile:files[i]];

       }

Above all code written in objective - c, but in swift AutoReleasePool is required?

Yes, it depends on code.  It’s a different story if your code is dealing with legacy Obj-C code, specially old Foundation classes in iOS.

To put it short, autoreleasepool is still useful in iOS/Swift development as there are still legacy Obj-C classes in UIKit and Foundation that call autorelease, but we not have to worry where there is pure swift code.



What is retain cycle or strong cycle?

Ans : 

According to ARC, variable should be one of three Strong, Weak or unowned. By default, variable has strong reference.

Let's take example :

class Employee {
var name  : String
var emid  : String
var title : String
init(name: String,emid: String, title: String) {
           self.name = name
   self.emid = emid
   self.title = title
        }

        deinit {
print("Employee : \(name) removed")
}
}

var manan : Employee? = Employee(name: "Manan", emid: "1234", title: "Sr iOS Developer")
manan = nil

Here deinit will be called and output will be "Employee Manan removed"

Now we add reference :

var sagar = manan
manan = nil

Here deinit will not be called due to adding reference. Here sagar has strong reference to variable which owned by manan before.

Now,

var sagar = manan
manan = nil
sagar = nil

Here deinit will be called and again output will be "Employee Manan removed"


Now let's discuss about Strong cycle :

Strong cycle occurs when two object has strong reference to each other. i.e objectA has strong reference to objectB and objectB has strong reference to objectA.


example :

class Employee {
var name  : String
var emid  : String
var title : String
var macBook : MacBook?
init(name: String,emid: String, title: String) {
           self.name = name
   self.emid = emid
   self.title = title
        }

        deinit {
print("Employee : \(name) removed")
}
}

class MacBook {
var serialNumber: String
var assignee : Employee?
        init(serialNumber: String) {
              self.serialNumber = serialNumber
        }

deinit {
print("Macbook : \(serialNumber) removed")
}
}

var manan : Employee? = Employee(name: "Manan", emid: "1234", title: "Sr iOS Developer")
var mac : MacBook? = MacBook(serialNumber: "ABC123")
manan?macBook= mac
manan = nil
mac = nil

Here, output :

Employee Manan removed
Macbook ABC123 removed

Why? Because here there is no strong reference from both side. So retain cycle is not yet created.

Now,

var manan : Employee? = Employee(name: "Manan", emid: "1234", title: "Sr iOS Developer")
var mac : MacBook? = MacBook(serialNumber: "ABC123")
manan?macBook= mac
mac?.assignee = manan
manan = nil
mac = nil

Output will be :

Nothing will be removed. Not output comes. Because of retain cycle. So there are strong relationship between both objects like manan has mac and mac is assigned to manan.

So, if we want to solve this problem we have to use weak or unowned reference for one side.

So,

weak var assignee : Employee?

Now output will be :

Employee Manan removed
Macbook ABC123 removed

So Now unowned : It is same as weak as it does not hold strong relationship with object. So when to use unowned : An unowned reference is used when the other instance has the same lifetime or a longer lifetime.

Difference between weak and unowned :


  • weak reference is used where there is possibility for that reference to become nil at some point during its lifetime. 
  • An unowned reference is used where there is no possibility for that reference becoming nil at any point until the self-object exist.
Example :

Every employee may or may not hold ICard but every ICard must be assigned to some one.
So Employee class has ICard variable as optional, but in ICard class, employee variable with optional and weak is not possible. If we want to use weak, we should make employee variable in ICard class optional. But we don't want that.

So, solution is that : 

unowned var employee : Employee

Now we are cleared about strong, weak and unowned and also our question : Retain Cycle or Strong Cycle.

Credit : Vinod Shwami

Difference between Strong and Weak in iOS

Ans : 


Strong
strong property means that you want to “own” the object. Only when you set the property to nil will the object be  destroyed. Unless one or more objects also have a strong reference to the object. This is the one you will use in most cases.
  1. Creates ownership between property and assigned value.
  1. This is default for object property in ARC so it does not let you worrying about reference count and release the reference automatically.
  1. It is replacement for retain. We use if and only if we need to use as retain.
  1. Retain count will be incremented.
  1. Creates non-ownerships between property and assigned value.
  1. Strong is used on parent object and weak is used on child object when parent is released then child object reference is also set to nil
  1. It helps to prevents retain cycles.
  1. It doesn’t protect the referenced object when collection by garbage collector.
  1. Weak is essentially assigned, un-retain property.
  1. Retain count will not be incremented.


Weak
Weak property means you don’t want to have control over the objects lifecycle. The object only lives on while another objects has a strong reference to it. If there are no strong references to the object then it will be destroyed. 
Weak reference is useful to avoid situation like retain cycle. Retain cycle occurs when two or more objects have strong reference to each other. This two object will never be freed in memory due to strong reference. So to avoid weak reference, One object has a strong ownership reference to another object, and another object should be have a weak reference to first object.

Strong references should be used when a parent object is referencing a child object and never the other way around. That is, a child class should not have a strong reference to the parent class.

Weak references should be used to avoid retain cycles and an object has the possibility to become nil at any point of it’s lifetime.

Good read : Click here




ARC - Automatic Reference Counting

Ans : Automatic Reference Counting is memory management feature in iOS that provides automatic referencing counting system. According to attribute type of property like retain and release, it increment and decrements reference count at runtime.

ARC is does not handle reference cycle automatically. 

Unlike garbage collection, ARC does not handle reference cycles automatically.


Default property attributes : 

i> Memory management : strong  weak  copy  assign 
ii> Thread Safety : atomic nonatomic
iii> Mutability : readwrite readonly

@property (strong, atomic, readwrite) NSArray *name;

For IBOutlet,

@property (nonatomic, retain) IBOutlet UILabel *label;


@property (weak) IBOutlet UILabel *instructions;
In 2015, apple recommend to use Strong.


To stop retain cycle, user should mention weak reference when needed.

Q : What is retain?
A.Retain works same as Strong according to apple document. If we assign retain, it will convert to strong or consider as Strong. 

Read : Difference between Strong and Weak attribute