Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding circular retention using ARC (strong/weak), learning some basics

I haven't seemed to run into a problem yet, but I'm trying to make sure I'm using some best practices.

Say I have a UITableViewController with a data source of an NSArray of MyObject objects. So in my UITableViewController I declare my data source like:

@property (strong, nonatomic) NSArray *dataSource;

Then after I touch a cell I want to push a new view that shows a detail view of something, using that cell's MyObject. So in the new UIViewController I have this:

@property (strong, nonatomic) MyObject *myObject;

Now in the UITableViewController when a cell is touched:

MyObject *myObject = [[self dataSource] objectForIndex:[indexPath row]];
NewView *view = [[NewView alloc] initWithMyObject:myObject];
// ... push onto nav controller, etc

Basically what I'm afraid of is my array is declared with strong, MyObject in the detailed view is declared with strong, and who knows maybe there is another view with the same MyObject declared with strong.

Bottom line: is this the proper way to pass an object in between views? I haven't really used a weak reference yet in my apps and I feel like that isn't right. Any help or links to help would be amazing.

like image 284
rnystrom Avatar asked Feb 21 '23 23:02

rnystrom


2 Answers

I think that what you need to understand is how arc works.

Basically whatever has a strong pointer pointing to it will be retained.

This works by adding a reference counter in the object so when you do this:

@property (strong, nonatomic) MyObject *myObject;

you create a STRONG pointer for myObject, (not the object).

but when you do this

MyObject *myObject = [[self dataSource] objectForIndex:[indexPath row]];

you make this pointer increase the reference counting on whatever you have in the specified index from that data source.

The important part is that as long as the pointer keeps pointing to this object it will be kept alive.

About your concern with the views.

Views created in the interface builder have their elements declared internally with strong pointers. This is when you want to use a weak reference. When you add your own IBOutlet to an element in the view it is good practice to make it weak. If you think about the reason logically, it basically means that you dont care about this interface builder element since you only want it to survive until the viewcontroller is deallocated.

When you usually encounter retain cycles is when an object has a child object, and this child object has a STRONG reference to its parent.

this is:

Object A creates object B with a strong pointer

Object B points to object A with a strong pointer

A will keep B alive and B will keep A alive.

This page will explain to you some basic stuff about how to avoid this kind of stuff:

http://cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

Also about passing objects between views, it is very very simple.

First get a pointer from View 1 to View 2 (can be strong or weak depending on who should be keeping view 2 alive, if its from the IB Builder it should be weak if its programatically it should be strong)

Second, make a property in view 2 (@property (strong, nonatomic) MyObject *myObject;)

now it is as simple as:

Self.view1Pointer.myObject = self.myOtherObject;

Understand here how both views are strongly pointing to this object so the object will be kept alive as long as 1 of the views hasnt been deallocated.

You wont create a retain cycle, you simply have the reference counting from that object set to 2.

Note: When a view is deallocated, all of its pointers are set to nil so any object being pointed by them will decrease in its reference count. IF it reaches 0 it is deallocated. (in the previous case myobject will be 1 because another view is still pointing to it).

The only scenario where you will create a retain cycle is if you manage to make myObject point strongly to View2 as well. So now they are keeping each other alive. (but as explained before you can make myObject point to view2 weakly which wont create a retain cycle).

You can learn more about arc here:

http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1

like image 143
Pochi Avatar answered Apr 29 '23 17:04

Pochi


It's not a retain cycle. It's a fine way to do things. The instance of MyObject doesn't strongly reference any of its owners, so when the last of those owners eventually gets released, so too will the object.

like image 30
warrenm Avatar answered Apr 29 '23 17:04

warrenm