Block, block

Source: Internet
Author: User

Block, block

The blog here is not very well maintained. I suggest you come here to read my blog. If you find any problem with your blog, please correct it. If you want to discuss iOS technology, please add my QQ group: 159974494

The second blog of the New Year in March 2, 2015.

This blog is suitable for those who have some knowledge about block. If you do not know what block is, this article may be more suitable for you.

Block implementation

Suppose you have some knowledge about Block. First, let's look at how the block is implemented.

int main() {    __block id obj = [NSObject new];    void (^blk)(void) = ^{        NSLog(@"%@",obj);    };    return 1;}

For such a block, we use clang tool to compile a. m (code file) into C Language

clang -rewrite-objc a.m

Find the. cpp file, which contains a lot of code. First, let's look at the definition of block.

/** Block object (struct) */struct _ main_block_impl_0 {void * isa; // Class pointer, pointing to the block Class int Flags; // used to save the block reference count, whether it is a stack, a stack, or a global zone, whether there is information such as the copy function int Reserved; // reserve the Variable void * FuncPtr; // function pointer, implement struct _ main_block_desc_0 * Desc to point to the block; // additional information of the block _ Block_byref_obj_0 * obj; // The captured variable };

There are two points in it that are not too clear,__main_block_desc_0And__Block_byref_obj_0Next let's take a look

/** Additional block information */static struct _ main_block_desc_0 {size_t reserved; // reserve the size_t Block_size variable; // The block size // copy and dispose functions. Copies the objects captured in the block to the heap and releases them. Void (* copy) (struct _ main_block_impl_0 *, struct _ main_block_impl_0 *); void (* dispose) (struct _ main_block_impl_0 *);}

We can see that__main_block_desc_0Is a struct used to save additional block information.

Let's take a look.__Block_byref_obj_0What is it?

Struct _ Block_byref_obj_0 {void * _ isa; // Class pointer _ Block_byref_obj_0 * _ forwarding; // when the block is copied to the stack, the block on the stack can also access the block int _ flags on the stack; // use bit to store some information, including whether the captured object is on the stack or on the stack int _ size; // struct size // For memory management, copy and dispose void (* _ Block_byref_id_object_copy) (void *, void *); void (* _ Block_byref_id_object_dispose) (void *); id obj; // captured object };

When we use the _ block parameter for a variable, the compiler automatically converts the variable__Block_byref_obj_0Object. Let's take a look.__Block_byref_obj_0Object details

The _ forwarding pointer is not very clear. Let's talk about it separately.

When a block is generated, __forwarding points to itself.

When the block is copied from the stack to the stack__Block_byref_obj_0_ Forwarding points to__Block_byref_obj_0. Stacked__Block_byref_obj_0_ Forwarding points to itself

When the block is copied from the stack to the stack, the block on the stack and the block on the stack may be used at the same time (in some places, only the block on the stack can be obtained ).__Block_byref_obj_0It will lead to data non-synchronization issues, so the code is not directly used everywhere.__Block_byref_obj_0Instead__Block_byref_obj_0The _ forwarding pointer.

In addition, we hope you can understand the Block capture relationship:
1. block (_ main_block_impl_0) Capture _ block (_ Block_byref_obj_0) obj
2. _ block (_ Block_byref_obj_0) capture an objectid obj

Block Problems 1. There are several types of block

There are three types of blocks:

2. What does block copy do?

Copy can be divided into three types based on different block types:

3. How to Avoid the circular reference of block 4. Why can a non-ARC, __block avoid circular reference?

First, let's look at the reasons for circular applications. In general, self holds the block, and the block holds the self, which is referenced cyclically. The hold in iOS is the guiding use count + 1.
1. Because the block is the property of self, when the block is generated, the Count + 1 will be referenced, so self holds the block.
2. To use a block, you must copy it to the stack. Otherwise, the block region on the stack will crash. The block object captures self as the attribute. When the block copy is to the stack, the block calls the copy function in _ main_block_desc_0 to make the self reference count + 1. Therefore, the block holds the self

When the _ block attribute is used, the block capture _ Block_byref_obj_0 object, __block_byref_obj_0 object, captures self. When block copy is performed, make the retainCount + 1 of the _ Block_byref_obj_0 object, and the block holds the _ Block_byref_obj_0 object, and the reference count of self will not increase, __block_byref_obj_0 object will not. So the block does not hold self and breaks the circular reference.

5. Why can't circular references be avoided in the __block under ARC?
_ Block id blockSelf = self; // ① here is the key void of the block holding self (^ blk) (void) =={ // ② ARC will not release blockSelf NSLog (@ "% @", blockSelf );};

Let's look at the above Code. In ARC, because blockSelf is of the _ strong type by default, retainCount + 1 at location ① and blockSelf Holds self. BlockSelf is captured in the block. As long as the block exists, the system will not release blockSelf. This indirectly causes the block to hold self.
In non-ARC scenarios, because retainCount + 1 is not performed at ①, block holding of self can be avoided.

Reference

Tang Qiao's blog

Objective-C advanced programming

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.