Circular reference--why ID is assign instead of retain

Source: Internet
Author: User

What is a circular reference

Simply put, a circular reference is: A retains B, B retains a, and neither a nor B can be released.

Why ID is assign and not retain

It can be guessed from the title of the article that the reason ID is assign rather than retain is related to your circular reference. The reason is true.

The ID is assign rather than retain, because retain may lead to circular references, note that the word here is possible, not necessarily.

Here is an example to illustrate the situation.

Note to strictly follow the memory management

First, create a protocol, the Protocol has a method, the function of the method is to change the color
1 #import <Foundation/Foundation.h>23@protocol zychangecolordelegate < Nsobject>45 -(void) changecolor; 6 7 @end
Ii. creating two View controller classes

1. View controllers A and B, two view controllers are added to the navigation, jump to B, click on the button on the B can change the background color of a. Here in order to explain why the ID is assign instead of retain, use proxy to pass the value, other methods do not discuss. The buttons on a and B are all implemented by XIB.

1.1 The first way to use retain does not cause circular references

Part of the code in the entry class

1 Zyaviewcontroller *aviewcontroller =//A  +1 =12 Uinavigationcontroller *navigationcontroller = [ [Uinavigationcontroller alloc] initwithrootviewcontroller:aviewcontroller]; //a +1 +1 =23 Self.window.rootViewController =//a  +1+1 +1 = 3//A 3-1 = 2// A 2-1 = 1   

Start by carefully calculating the reference count for a and B from the Ingress class

1 //A2 #import<UIKit/UIKit.h>3 4 #import "ZYChangeColorDelegate.h"5 6 @interfaceZyaviewcontroller:uiviewcontroller <ZYChangeColorDelegate>7 8 @end9 Ten // ---------------------------------------------------------------------------------- One  A #import "ZYAViewController.h" - #import "ZYBViewController.h" -  the @implementationZyaviewcontroller -  -  -- (void) Viewdidload + { - [Super Viewdidload]; +      A } at  --(Ibaction) GoToNext: (ID) Sender - { -Zybviewcontroller *bviewcontroller =[[Zybviewcontroller alloc] init]; //B +1  -Bviewcontroller.Delegate=Self ; //A 1 +1 = 2  - [Self.navigationcontroller Pushviewcontroller:bviewcontroller Animated:yes]; //B 1 +1 = 2  in [Bviewcontroller release]; //B 2-1 = 1  - } to  + #pragmaMark-Protocol method -- (void) ChangeColor the { *Self.view.backgroundColor =[Uicolor Redcolor]; $ }Panax Notoginseng  -- (void) Dealloc the { + [Super Dealloc]; A } the  + @end
1 //B2 #import<UIKit/UIKit.h>3 4 #import "ZYChangeColorDelegate.h"5 6 @interfaceZybviewcontroller:uiviewcontroller7 8@property (nonatomic, retain)ID<ZYChangeColorDelegate>Delegate;9 Ten @end One  A // ------------------------------------------------------------------------------ - #import "ZYBViewController.h" -  the @implementationZybviewcontroller -  -- (void) Viewdidload - { + [Super Viewdidload]; -     + } A  at-(Ibaction) Changeabackgroundcolor: (ID) Sender - { - [_delegate ChangeColor]; - } -  -- (void) Dealloc in { - [_delegate release]; //A 2-1 = 1  to [Super Dealloc]; +}//When you click the Back button on the navigation bar to get B from the navigation controller pop, the reference count changes to B 1-1 = 0, this time the Dealloc method of B is called, the reference count of a is reduced by 1, and a also pops out of the navigation (where a is the root belongs to the rabbit control When the program ends), the reference count is a 1-1 = 0, and A's Dealloc method is called. 

The above scenario does not cause a circular reference because the reference count of a and B is changed to 0 at the appropriate time, and the respective dealloc methods are called.

The following is a case that causes a circular reference

2. Using retain to cause a circular reference, the value needs to be slightly modified: Add a property (or member variable) to a

1 //A2 #import<UIKit/UIKit.h>3 4 #import "ZYChangeColorDelegate.h"5 #import "ZYBViewController.h"6 7 @interfaceZyaviewcontroller:uiviewcontroller <ZYChangeColorDelegate>8 9@property (nonatomic, retain) Zybviewcontroller *Bviewcontroller;Ten  One @end A  - // ----------------------------------------------------------------------------- - #import "ZYAViewController.h" the  - @implementationZyaviewcontroller -  -  +- (void) Viewdidload - { + [Super Viewdidload]; A      at } -  --(Ibaction) GoToNext: (ID) Sender - { //note differs from the first notation  -_bviewcontroller =[[Zybviewcontroller alloc] init]; //B +1 = 1  -_bviewcontroller.Delegate=Self ; //A 1 +1 = 2  in [Self.navigationcontroller Pushviewcontroller:_bviewcontroller Animated:yes]; //B 1 +1 = 2  - } to  + #pragmaMark-Protocol method -- (void) ChangeColor the { *Self.view.backgroundColor =[Uicolor Redcolor]; $ }Panax Notoginseng  -- (void) Dealloc the { + [_bviewcontroller release]; A [Super Dealloc]; the } +  - @end

The reference count for A and B is now calculated from the Ingress class: At this point, when you leave from the B interface, B pops out of the navigation, the reference count of B is reduced by 1, and the 1,dealloc method is called only when its reference count is 0, so at this point a cannot be released once, and the reference count is 2, when a pop out of the navigation, its reference count is 1, also cannot call the Dealloc method. So neither A nor B can be released, thus forming a form:

B to release himself after the stack found himself a reference count of 1 and then found that as long as a dealloc method executed B can be released to find a go

A want to perform your own Dealloc method to release yourself find if the navigation frees itself, its reference count is still 1 and then finds out that as long as B's Dealloc method executes a, it can be released to find B.

This makes it possible for both parties to release themselves because of the circular reference.

Third, use assign to avoid circular reference

With assign, the reference count is not added to 1 to avoid the case of circular references.

Circular reference--why ID is assign instead of retain

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.