Tigran Iskandaryan
Tigran Iskandaryan

Reputation: 1451

Trying to understand the reference cycle

I was reading Apple's documentation about Objective-C's reference cycles and then I tried to create one, but I can't quite understand its behaviour. Here what I have: there are two classes XYZPerson and XYZPersonSpouse. They have properties for their first name, last name and properties of type NSString called spouseName. In main I set spouseName properties of both classes to each others name like this (in init of both classes I call their designated initializers, which set their first names and last names):

 XYZPerson *person = [[XYZPerson alloc] init];
 XYZPersonSpouse *spouseOfXYZPerson = [[XYZPersonSpouse alloc] init];


 spouseOfXYZPerson.spouseName = person.firstName;
 person.spouseName = spouseOfXYZPerson.firstName;

I also override dealloc method of both classes to print some text on the console. Now, because I don't use weak or unsafe_unretained, while defining properties spouseName on both classes, I assume that by the code above I created a strong reference cycle. However, when later I assign another NSString as a name of XYZPerson class's instance person like this:

 person.spouseName = @"Julia";

(but even without this) and run my project, I keep seeing the message for the dealloc method of XYZPersonSpouse class (and for XYZPerson, too).

Shouldn't the classes still not be kept because of the reference cycle? If you could explain what is going on here, I would appreciate your help.

Upvotes: 2

Views: 101

Answers (1)

AdamPro13
AdamPro13

Reputation: 7400

You aren't seeing a reference/retain cycle because this isn't a reference cycle.

In your example, person and spouseOfPerson are objects with strong pointers to their string properties firstName and spouseName. These person objects don't have strong pointers to each other, they have strong pointers to the strings. Since the strings don't have strong references to the person objects, no cycle is created.

If you want to create a reference cycle, you need the objects themselves to have strong pointers to each other. To do that, you will want to declare the following properties:

XYZPerson
@property (nonatomic, strong) XYZPersonSpouse *spouse

XYZPersonSpouse
@property (nonatomic, strong) XYZPerson *spouse

If you then do the following instead of the two lines where you set the names, you will have a reference cycle.

spouseOfXYZPerson.spouse = person;
person.spouse = spouseOfXYZPerson;

To break the reference cycle, change either spouse property to weak.

Upvotes: 3

Related Questions