Objective Language Learning (OC)-circular reference
In the previous article, we introduced the reference problem when operating objects in arrays and the concept of automatically releasing a pool:
Today, let's continue to look at a pain point in the reference count: circular reference
Here we will not explain the circular references too much, that is, multiple objects are referenced to each other to form a ring.
Let's look at a specific example:
Mutual reference between the Dog class and the Person class
Dog. h
//// Dog. h // 29_CyclePointer /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import
# Import Person. h @ interface Dog: NSObject // retain is not used here. If retain is used, a circular reference @ property (nonatomic, assign, readwrite) Person * person;-(void) dealloc is formed; @ end
Dog. m
//// Dog. m // 29_CyclePointer /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import Dog. h @ implementation Dog-(void) dealloc {// [_ person release]; NSLog (@ dog dealloc); [super dealloc];} @ end
The Dog class has a property of the Person type.
Person. h
/// Person. h // 29_CyclePointer /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import
@ Class Dog; @ interface Person: NSObject @ property (nonatomic, retain, readwrite) Dog * dog;-(void) dealloc; @ end
Person. m
/// Person. m // 29_CyclePointer /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import Person. h # import Dog. h @ implementation Person-(void) dealloc {[_ dog release]; NSLog (@ Person dealloc); [super dealloc];} @ end
The Person class has the Dog type attribute.
Let's take a look at the test code.
Main. m
//// Main. m // 29_CyclePointer /// Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import
# Import Dog. h # import Person. h // circular reference // This is a very troublesome task. It relies entirely on the experience of int main (int argc, const char * argv []). {Person * p = [[Person alloc] init]; Dog * dog = [[Dog alloc] init]; [p setDog: dog]; // dog count: 2 [dog setPerson: p]; // person count: 2 [p release]; // person count: 1 [dog release]; // dog count: 1 // The reason for the release is that the dealloc method is not executed, and the release code in it is not executed. The dog and person are waiting for each other, forming a loop // The solution version is to cut off the connection between them // @ property does not use retain, use assgin NSLog (@ is over); return 0 ;}
We define a Person object and a Dog object, and then reference each other. But when we call their release method, these two objects are not released.
The reason is simple:
The person and dog references each other. When the release method is executed, the reference count is still 1, so the dealloc method will not be called.
The dealloc method is not executed, and the release code in it is not executed. The dog and person are waiting, forming a ring.
The solution is:
Disconnect them
When defining an attribute in one Party, @ property does not use retain and assgin
At the same time, the release method is no longer called in the dealloc method.
In the above example, we can see that assgin is used in the Dog class.