[Reading notes]ios with OS X multithreading and memory management [blocks section-4]

Source: Internet
Author: User

2.3.5 __block variable storage domainThe effect of block variables on __block variables when they are copied from the stack to the heap
__block variable storage field impact
stack copied from stack to heap and held by block
when using the __block variable in multiple blocks, the __block variable is also copied from the stack to the heap when the first block is copied from the stack to the heap. When the subsequent block is copied from the stack to the heap, the __block variable is held by the block, and the __block variable reference count is incremented. Previously, the __forwarding in the __BLOCK variable structure could do "regardless of whether the __block variable is accessible on the stack or on the heap" because the __block variable on the stack is copied to the heap, and the value of his member variable __forwarding is replaced with the __ on the copied heap. The address of the block variable.
2.3.6 Intercept Objectslook at the following code:
    typedef  void (^ablock) ( ID);
Ablock Ablock;
{
ID array=[[NsmutablearrayAlloc]Init];
ablock=^ (ID objct) {
[Array AddObject: OBJCT];
NSLog(@ "Array count%d", [ArrayCount]);
};

}
Ablock ([[NSObjectAlloc]Init]);Ablock ([[[nsobjectalloc]init]);
The author writes: "After executing the code, the program forces the end, and the array is discarded with the end of the scope of the variable." But in my actual operation, the array object is working normally and the program is running normally (Xcode5.1.1 and Xcode6.1). So maybe Apple has modified this mechanism, the author's conclusions about intercepting objects are no longer listed, and the rules for intercepting objects can refer to the rules for intercepting automatic variables. This section refers to the _block_object_assign function and the _block_objec_dispose function, the former equivalent to the Retain method, Assigning an object to a struct member variable of an object type (such as adding an object to an array in the preceding code), which is equivalent to the release method, releases an object that is assigned to a struct member variable of the object type (such as releasing an object from an array). The block is copied from the stack to the heap in the following cases:
    • Call the copy instance method of block
    • Block as function return value
    • When a block is assigned to a class or block type member variable with the __strong modifier ID type
    • When a block is passed in a method name that contains a Usingblock cocoa framework method or a Grand Central dispatch API.

In addition to the following scenarios, it is recommended to call the copy instance method of block (that is, if the system is automatically called, I do not need to call):
    • When a block is returned as a function value
    • When a block is assigned to a class or block type member variable with the __strong modifier ID type
    • When a block is passed in a method name that contains a Usingblock cocoa framework method or a Grand Central dispatch API.



2.3.7 __block objects and variables This section follows the previous section conclusion, skipping over
2.3.8 Block Circular reference
person.m File Code
Main program code:{...Person *per=[[person alloc]init]; NSLog(@ "O"); ...}
The result of the execution is that the Dealloc method in the source code is not called. The reason is that the object of the person class holds the ID type variable self in blk_,blk_. And because the block syntax is assigned to the member variable Blk_ (in this case the ARC mode, the variable defaults to __ Strong type), so the block on the stack is copied to the heap and holds the self that is used, which creates a circular reference. The compiler also gives a warning. to avoid circular references, you can use the __weak modifier variable and assign self to the variable. as follows:
-(ID) init{
Self=[SuperInit];
ID __weak tmp= Self;
Blk_=^{
NSLog(@ "Self%@", TMP);
};
return Self;}
in this code, because when a block exists, the person object holding this block must exist (Blk_ belongs to the person object), so you do not need to empty the TMP. In iOS4 and earlier versions, there is no arc mechanism, and the __unsafe_unretained modifier is used instead of the __weak modifier. The following code also causes circular references because the obj used in the block syntax belongs to the object's member variable, and if you want to intercept the object's member variables, you naturally intercept the object itself.
//arcOpen State
@interface Person(){
void(^blk_) (void);
ID obj;
}
@end
@implementation Person
-(void) dealloc{
NSLog(@ "Person Dealloc");
}
-(ID) init{
Self=[SuperInit];
Blk_=^{
NSLog(@ "obj%@",obj);
};
return Self;}

using the __block variable also avoids circular references, as in the following code:
//arcOpen State
@interface Person(){
void(^blk_) (void);
}
@end
@implementation Person
-(void) dealloc{
NSLog(@ "Person Dealloc");
}
-(ID) init{
Self=[SuperInit];
__block ID tmp= Self;
Blk_=^{
NSLog(@ "obj%@", TMP);
tmp=Nil;
} ;
return Self;
}
-(void) execblock{
Blk_();
}
The code does not cause a circular reference, but if you do not call the Execblock method, which does not perform an assignment to TMP, it will cause a circular reference.
  • The person class object holds block;
  • Block holds __block variable
  • __block holding Person Class object
by executing The execblock,__block variable tmp invalidates the strong reference to the person class object.

using __block variables to avoid circular references has the following advantages,
    • Control the holding time of an object by __block variable
    • Instead of the __unsafe_unretained modifier in an environment where you cannot use the __weak modifier, you do not have to worry about dangling pointers.
The disadvantage is that block must be executed to avoid circular references.
2.3.9 copy/release
When arc is invalid, it is necessary to manually copy the block from the stack to the heap, copy it using the Copy method, release method. As long as the block is on the heap, it can be held by the Retain method, which has no effect on the block call retain method on the stack. Block can also be made in C, using Block_copy and block_release instead of Copy/release instance methods. In addition, when arc is invalid, the __block specifier is used to avoid block circular references, because when the block is copied from the stack to the heap, if the variable used by the block is an ID type object with an __block specifier or an object type automatic variable, it will not be retain, otherwise if there is no _ The _block specifier is retain. when arc is valid and invalid, the purpose of the __block specifier is very different, please note.


The block section ends here.

[Reading notes]ios with OS X multithreading and memory management [blocks section-4]

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.