(4)-the cycle reference of arc is easy to fly

Source: Internet
Author: User
Concept

When we use strong references, we often need to pay attention to the circular references. Circular references mean that two objects are strongly referenced by each other, so that no object can be released.

In general, when there is a "parent-child relationship" between objects, strong references usually occur. For example, the relationship between the addrbook object and each address book entry is as follows.

In this case, the entry object cannot be released because it is strongly referenced by addrbook. On the other hand, if the entry is released, the strong reference of the addrbook object will no longer exist, and the object should also be released.

Solution

As in the preceding example, when multiple objects have a parent-child relationship, you need to use a weak reference on one side to solve the circular reference problem. In general, "father" is the owner of "child" and is a strong reference for "child", while "child" is a weak reference for the father.

When the variables of the strong reference addrbook object are released, the addrbook object is automatically released, and the strong reference of the entry member object is lost. In addition, when the addrbook object is released, the addrbook variable in the entry object will also be automatically brought into nil by the zeroing mechanism. We don't need to worry about releasing objects and then asking questions.

Next, let's take a look at several situations where you need to pay attention to the circular references.

Delegate Mode

The delegate mode is often used in iOS programs. For example, in viewcontroller, when you use modalview to enable/disable detailviewcontroller, you must set the delegate mode.

Here, the viewcontroller object strongly references the detailviewcontroller. If the delegate of the detailviewcontroller is not a weak reference to the viewcontroller, the loop reference will occur.

In addition, when the delegate variable declared by weak @ property is used in the class, if the reference object is released, the variable will be automatically set to nil without program code settings.

Blocks

Blocks is imported from IOS 4 and can be understood as Lambda in Python or lisp. This concept has also been imported in C ++ 11. Similar concepts are also defined in ruby, smalltalk, and JSP. For more information, see the subsequent articles. In this section, we will mainly look at the circular references in block.

For example, when a block object is defined using the copy attribute,

typedef void(^MyBlock)(void);@interface MyObject : NSObject@property (nonatomic, copy) MyBlock block;@property (nonatomic, strong) NSString *str;- (void)performBlock;@end@implementation MyObject@synthesize block, str;- (void)performBlock {    if (self.block) {        self.block();    }}@end

The call end is as follows:

MyObject *object = [[MyObject alloc] init];object.str = @"hoge";object.block = ^{    NSLog(@"block: str=%@", object.str);};[object performBlock];

We can see that the block structure references the object, and the object also strongly references the block.

To solve this problem, we can have the following two options.

Use the _ block keyword to modify

Use the _ block keyword to grant the object read and write permissions. If the block processing is complete, the object will be released.

__block MyObject *object = [[MyObject alloc] init];object.str = @"hoge";object.block = ^{    NSLog(@"block: str=%@", object.str);    object = nil;};[object performBlock];

This keyword allows the block to cancel strong object references to avoid circular references. However, one problem is that the object release action is performed within the block. If the block is not executed, the cycle reference will always exist. For example, if the above Code contains 8th rows of [object into mblock]; if it is not executed, it will still be in the cyclic reference state.

Use the _ weak keyword to modify

Another solution is to change block references to weak references.

MyObject *object = [[MyObject alloc] init];object.str = @"hoge";__weak MyObject *weakObject = object;object.block = ^{    NSLog(@"block: str=%@", weakObject.str);};[object performBlock];

Considering the use of Blocks During asynchronous communication, the weak variable weakobject may change to nil at any time, so it is similar to the following: change to the strong variable first, and check whether the NIL processing method should be safer.

MyObject *object = [[MyObject alloc] init];object.str = @"hoge";__weak MyObject *weakObject = object;object.block = ^{    MyObject strongObject = weakObject;    if (strongObject) {        NSLog(@"block: str=%@", strongObject.str);    }};[object performBlock];

In general, when we use blocks, we also need to consider the relationship between the variables in the block and the instance. Do not cause unnecessary circular references.

  • Blogger: Yi Feifei
  • Link: http://www.yifeiyang.net/development-of-the-iphone-simply-4/
  • Reprinted text.
  • 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.