Block parsing of iOS development

Source: Internet
Author: User
Tags readable

1. The nature of block is a Objective-c object. Why do you say that?

In the objective-c. Runtime will be rated for the type of the object at execution time, depending on the object's Isa pointer point. Can also feel an object. It has an Isa pointer. is an OC object

2. How do you know that block has an Isa pointer? We can see the implementation of block in the future by Clang command.
//測试代码int main(intconstchar * argv[]) {    @autoreleasepool {        void(^blk)(void)=^{            NSLog(@"hello lx");        };    }    return0;}

After conversion: Block syntax is converted to the following structure by the compiler

struct   __  main_block_impl_0 {struct  __  block_ Impl impl ;  //block implementation of the relevant information  struct  __  main_block_desc_0* desc;  Descriptive narrative information of //block  __  main_block_impl_0 (void *fp, struct  __  main_block_desc_0 *desc, int  flags=0 ) {impl . Isa = &_     Nsconcretestackblock; impl .    Flags = flags; impl .    funcptr = FP;  desc = desc; }};

This struct is composed of three parts Impl structure (block object) +DESC structure pointer + constructor, the constructor is used to initialize the struct, the remaining two structures corresponding implementation such as the following

//impl的类型,block的相关实现信息struct __block_impl {  void *isa;//看到了isa指针,说明block是一个isa指针。对于他的类后面会讲到  int Flags;//标志  int Reserved;//  void *FuncPtr;//函数的实现。指向了block所相应的函数的实现地址:由于 block 相当于一个匿名的函数指针};//对于block的描写叙述信息struct __main_block_desc_0 {  size_t reserved;  0sizeof(struct __main_block_impl_0)};
Summarize the above code:

The block syntax is converted to a __MAIN_BLOCK_IMPL_0 structure by the compiler. This structure is composed of three parts: the _BLOCK_IMPL structure of the relevant implementation information of the block and the impl of the description information of the storage block __MAIN_BLOCK_DESC_ 0 struct Pointer desc and the construction method used to initialize the block. The members of ISA in Impl indicate that block is an OC object. Another function pointer points to the implementation of the block

3. Block: In fact, the equivalent of the anonymous function in the C language. He was able to access external variables or objects


    • Block the difference between an anonymous function and a normal function

1. There is no function name, the most pure block ^{ printf("hello"); }; , the most pure function of the minimum to have a functional name
2. With caret ' ^ '
3. Function nesting is not supported in either the C language or the OC function. However, block implements this function. It is equivalent to a function. But his sight was in the interior of another function.
Types of access to ask #
  1. Own active variable: is the local variable. The local variable is equivalent to the value passed at the time of the function call and does not agree with the change: when visiting an external variable, the Block object adds his own active variable as a struct member to his struct, and the same value as the original variable, and the reason why it cannot be changed is that They are not connected except for values, which are equivalent to value passing. As mentioned above, block is equivalent to a function, and two functions have the same local variables. One change doesn't have an effect on the other, so the compiler simply forbids it. Implementations such as the following
//block access to external self-active variablesstruct __Main_block_impl_0 {struct __Block_implImpl;struct __main_block_desc_0* desc;intA//The variable to which it is visited is added to its own structure, and no access is not included  __Main_block_impl_0 (void *FP,struct __Main_block_desc_0 *desc,int _Aintflags=0): A (_A) {Impl. ISA = &_Nsconcretestackblock;Impl. Flags = flags;Impl.    funcptr = FP;  desc = desc; }};
#

2. static variables. Within its scope there is only one memory, which is readable and writable. Equivalent to the address passing at the time of the function call, the block joins the address of the external static variable that it has visited into its own struct member. With the address, the value of what is not able to achieve, such as the following

//Intercept static variable valuesstruct __Main_block_impl_0 {struct __Block_implImpl;struct __main_block_desc_0* desc;int*a;The address of an external static variable that is more than an access to an external variable .  __Main_block_impl_0 (void *FP,struct __Main_block_desc_0 *desc,int*_Aintflags=0): A (_A) {Impl. ISA = &_Nsconcretestackblock;Impl. Flags = flags;Impl.    funcptr = FP;  desc = desc; }};
#

3. Global variables: The global access to the question. In the global symbol table, there is no difference between access to the block, readable and writable, and no matter how you can access
For the difference between static and global variables, to be able to poke here I feel able to point

#

4. Object. Block can read objects.

#

5. Properties of an object: readable and writable

#

6: For member variables
Self-implicit circular reference: for one or more member variables, whether or not modified by __block. The block structure realizes its own initiative to generate a member of self. It also refers to the object instance to which the member variable belongs, and the self changes to the member variable are implemented by the object's own pointer reference, and the reference to the member variable inside the block is implemented by the member self pointer of the block struct object (but causes a circular reference).

4. How to allow block to change the value of the intercepted self-active variable by 4. Change the value of the external variable intercepted by the block

It says: Block can not change its own active variable or object point, this time, __block like a savior in front of us now, __block is how to implement changes to their own active variable value, see his implementation

struct __Main_block_impl_0 {struct __Block_implImpl;struct __main_block_desc_0* desc;__Block_byref_a_0 *a;//More than one __BLOCK_BYREF_A_0 structure pointer  __Main_block_impl_0 (void *FP,struct __Main_block_desc_0 *desc,__BLOCK_BYREF_A_0 *_Aintflags=0): A (_A->__forwarding) {Impl. ISA = &_Nsconcretestackblock;Impl. Flags = flags;Impl.    funcptr = FP;  desc = desc; }};//The block-modified self-active variable is saved with the address of such a struct-body pointerstruct __block_byref_a_0 {void *__iSa//point to its corresponding class__BLOCK_BYREF_A_0 *__forwarding;//point to itself int __fLagsint __SizeintA//self-active variable value};Staticvoid__Main_block_func_0 (struct __MAIN_BLOCK_IMPL_0 *__CSelf) {__Block_byref_a_0 *a =__cself->a;//bound by ref(a->__fORWARDING->A) = -; printf"%d", (a->__fOrwarding->a)); }

As can be seen from the above, when using __block to modify the active variable, this variable becomes a struct __Block_byref_a_0 struct instance, the struct has a pointer to itself. Forwarding to ensure that the variable can be correctly visited wherever it is located. (Detailed later)
The process of altering a variable: Impl will find itself by locating the farwarding pointer based on the pointer struct __Block_byref_a_0 to the struct instance you saved. When you find your own active variable stored inside, change his value.

5. Block's storage domain

In the front, we found that block nature is an object. He has an Isa pointer pointing to its corresponding class, so what is his class, which involves the storage domain of the block?

There are three types of blocks stored in the domain, with the ISA pointer pointing to one of the three
1. _NSConcreteStackBlock: stored on the stack
2. _NSConcreteGlobalBlock : stored in data area
3. _NSConcretMallocBlock : Stored on the heap

For these three types of usage

_nsconcreteglobalblock:
1. All global blocks are stored in the data area
2. Assuming the block does not intercept its own active variable, block is also in the data area

_nsconcretestackblock:
1. MRC: Default in the Stack area, the block life cycle is related to its scope
2.ARC: Most of the blocks in the ARC case are stored in the heap. There are only a few parts in the stack area. We need to manually copy to the heap area in the stack area.
_nsconcretmallocblock
MRC: Copy blocks can be copied from the stack to the heap area using the Copy method
ARC: Most of the default in the heap area, the stack can be copied to the heap area by Copy/strong, only a strong point to him, will be copied to the heap area

6. Copy the block from the stack to the heap via copy

The life cycle of a variable on a stack is managed by the compiler and is associated with its scope. Out of scope will be released. But there's a program on the heap. Ape's own management, or arc management, will not be released because of its scope

A forwarding pointer is mentioned earlier, and the block-modified self-active variable is stored in a __Block_byref_a_0的 struct pointer. This pointer also has a point to its own forwarding, then why not directly find its corresponding value, and to pass this pointer, because when the block object is assigned from the stack on the heap. The block-modified variables that are used internally are also assigned a copy on the heap, and then the forwarding struct pointer on the stack points to the structure on the heap so that it can be guaranteed on both the stack and the heap. are able to access the variables correctly

No manual copy required under ARC
  1. When a block is strongly referenced
  2. When Usingblock is in the system's API
  3. Block as function return value

When do we need to copy it manually?

When block is a function parameter, the block we define under ARC is written in copy.

About the features of copy

  1. Assume that the original is on the stack, through copy. are copied onto the heap.

  2. Assuming the original is in the global data area, there will be no change
  3. Assuming the heap area: its reference count plus 1
7. __block difference between arc and MRC

1, with __block modification, whether in the MRC or arc, can change their own active variable value
2, in the MRC will avoid circular reference, because the MRC under the __block modified variable will not be reatin, so will not be held by block, so can avoid circular reference
3, in Arc to solve the circular reference is WEAK:ARC under the circular reference is not __block caused, is due to the characteristics of arc. The default is strong references, so in order to resolve circular references, self is generally decorated with weak

8. Why use Copy to decorate block

Use copy to transfer blocks from the stack to the heap
Under MRC, the default is on the stack to copy the block's lifecycle to control it. Not enough to replace Reatin.

Most of the conditions under arc are on the heap by default. But because the general tradition, will write the copy, but can use strong to replace.

Block parsing of iOS development

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.