ArticleDirectory
Concept
When we use strong reference, we often need to pay attentionCycle reference. 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. Generally, "father" is the owner of "child", and "child" is a weak reference for "child.
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
IOSProgramIt is often used in the delegate mode. For example, in viewcontroller, when you use modalview to enable/disable detailviewcontroller, you need to set the delegate.
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 the programCode.
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,
123456789101112131415161718 |
typedef void (^ myblock) ( void ); @ interface myobject : nsobject @ property (nonatomic, copy) myblock block ; @ property (nonatomic, strong) nsstring * STR ; -( void ) extends mblock ; @ end @ implementation myobject @ synthesize block , STR ;-( void ) extends mblock { If ( Self . block) { Self . block () ;}< SPAN class = "keyword"> @ end
|
The call end is as follows:
1234567 |
Myobject*Object= [[MyobjectAlloc] init]; object. Str = @"Hoge"; Object. Block = ^ {nslog (@"Block: Str = % @", Object. Str) ;}; [object callback mblock]; |
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.
12345678 |
_ Block myobject * object = [[MyobjectAlloc] init]; object. Str = @"Hoge"; Object. Block = ^ {nslog (@"Block: Str = % @", Object. Str); object =Nil;}; [Object callback mblock]; |
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.
12345678 |
Myobject*Object= [[MyobjectAlloc] init]; object. Str = @"Hoge"__Weak myobject * weakobject = object; object. Block = ^ {nslog (@"Block: Str = % @", Weakobject. Str) ;}; [object callback mblock]; |
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.
1234567891011 |
Myobject*Object= [[MyobjectAlloc] init]; object. Str = @"Hoge"__Weak myobject * weakobject = object; object. Block = ^ {Myobject Strongobject= Weakobject;If(Strongobject) {nslog (@"Block: Str = % @", Strongobject. Str) ;}; [object callback mblock]; |
In general, when we use blocks, we also need to consider the relationship between the variables in the block and the instance, and do not cause unnecessary circular references.