Definition and use of block code blocks for IOS

Source: Internet
Author: User

The essence of a code block is similar to other variables, where the data stored by a block of code is a function body. With code blocks, you can invoke the same calls as other standard functions, pass in parameters, and get the return value.
The caret is a code block syntax tag. Represents the definition of a code block.

1. Basic use of code blocks

        No parameter no return value        void (^myblock) () = ^ ()        {            NSLog (@ "Hello, world!");        };        Myblock ();                With parameter no return value        void (^myblock2) (nsstring *string) = ^ (NSString *string) {  NSLog (@ "%@", string);};        Myblock2 (@ "Hello, World myblock2!");                 No parameter has return value        int (^myblocksss) () = ^ (int i) {return;};        int c = myblocksss ();        NSLog (@ "%i", c);                There are parameters with the return value        int (^MYBLOCK3) (int) = ^ (int i) {return * i;};        int i = MYBLOCK3 (3);        NSLog (@ "%i", I);

2, rename the block with typedef

Renaming a block with a typedef is the same as renaming a function pointer:

  copyright©2016 year Liujun. All rights reserved.//#import <foundation/foundation.h>typedef int (^ myblock) (int a,int b); int main (int argc, cons T char * argv[]) {    @autoreleasepool {        //Insert code                here ... __block int n = +;                Myblock block = ^ (int a,int b)        {            n = 20;//But no __block adornment code is not compiled by                        return n + a + b;        };                NSLog (@ "%i   %i", N, Block (3,4));//Output  result   :                NSLog (@ "%i   %i", Block (3,4), n);//output result        +//above output. The description code block is executed                NSLog (@ "Hello, world!") at the time of the call;    }    return 0;}

  

3.Block in-memory location

According to the location of block in memory is divided into three types of Nsglobalblock,nsstackblock, Nsmallocblock.

Nsglobalblock: Similar function, in text segment;
Nsstackblock: In stack memory, block will be invalid after function return;
Nsmallocblock: In heap memory.

//copyright©2016 year Liujun. All rights reserved.//#import <foundation/foundation.h>typedef Long (^sum) (int,int); int main (int argc, const char            * argv[]) {@autoreleasepool {//Insert code HERE...V Sum sum1 = ^ long (int A, int b) {        return a + B;        };  NSLog (@ "sum1 =%@", sum1);//print Result: Sum1 = <__nsglobalblock__: 0x47d0> int base        = 100;        Sum sum2 = ^ long (int A, int b) {return base + A + B;        }; NSLog (@ "sum2 =%@", sum2);        Print Result: sum2 = <__nsmallocblock__: 0xbfffddf8> Sum sum3 = [sum2 copy]; NSLog (@ "sum3 =%@", sum3);    Print Result: sum3 = <__nsmallocblock__: 0x902fda0> NSLog (@ "Hello, world!");} return 0;} 

Nsglobalblock, we just have to implement a block that doesn't have a reference to the surrounding variable, it will be shown as it. If a reference to a defined environment variable is added, it is nsstackblock. So where does Nsmallocblock come from? The term malloc is actually familiar to everyone, when allocating dynamic memory on a heap. Yes, if you use Block_copy () or send a copy message for a Nsstackblock object, you get Nsmallocblock. Several of the conclusions in this paragraph can be derived from the code experiment.

You will also get the following attention points for the use of block.

For global block, we don't need to deal with retain and copy, because even if you do, it doesn't seem like much. For a stack block, if you don't do anything, it will go to the top and go to the stack frame to fend for itself. And if you want it to take longer than stack frame, call block_copy () and let it move to heap memory. In the case of blocks already on the heap, do not expect "real copy" through copy, because its reference to the variable will still be the same, in this sense, the role of copy and retain is very similar.

4, the use of external parameters in the code block

The difference between BLK1 and BLK2 is that:

BLK1 does not use any external variables other than block, the block does not need to create a snapshot of the local variable value, which makes Blk1 no different from the general function .

The only difference between BLK2 and BLK1 is that the local variable base is used, when the definition (note is "definition", not "Run") BLK2, the local variable base current value is copied to the stack as a constant for block use . Execute the following code, and the result is 203 instead of 204.

int base = +;    Base + + +;    Blksum sum = ^ long (int A, int b) {      return base + A + B;    };    base++;    printf ("%ld", sum);  

The variable base in the block is read-only, and if you want to change the value of base within the block, use __block when you define base: __block int base = 100;

__block int base = +;  Base + + +;  Blksum sum = ^ long (int A, int b) {    base + = ten;    Return base + A + B;  };  base++;  printf ("%ld\n", sum);  printf ("%d\n", base);

The output will be 214,211. When you use a __block-modified variable in a block, the variable is run at the moment, not a snapshot at the time of definition. In this example, when the sum is executed, base takes the value after base++, which is 201, then executes the blockbase+=10; Base+a+b, the running result is 214. When the block is executed, base has become 211.

static variables, global variables: If you change the base of the previous example to global, or static. The block will be able to read and write to him. Because the address of a global variable or static variable in memory is fixed, block reads the value of the variable directly from its memory and gets the latest value, not the constant that was copied at the time of definition.

static int base = N;  Blksum sum = ^ long (int A, int b) {    base++;    Return base + A + B;  };  base = 0;  printf ("%d\n", base);  printf ("%ld\n", sum); Here the output is 3, not 103  printf ("%d\n", base);  

The output is 0 4 1, which indicates that the update of base outside the block will affect the value of base in block, and that the block's update to base will also affect the base value outside the block.

The block variable, the variable modified by __block, is called the block variable. A block variable of the base type is equivalent to a global variable, or a static variable.

5, circular Reference

The root of the retain cycle problem is that blocks and obj can be strongly referenced to each other, retain each other, which leads to retain cycle, and finally the block and obj become islands, and no one can release anyone. Like what:

@implementation Tsetblock    -(ID) init{       if (self = [superinit]) {         self.teststr [email protected] "China";          Self.block = ^ (NSString *name, NSString *str) {             NSLog (@ "arr:%@", self.teststr);//Compile Warning: Capturing ' self ' strongly in th is block are likely to leads to a retain cycle         };     }     returnself;  }  @end  

Most of the online posts are expressed as "self causes circular references in block," but is that really the case? I doubt that such a statement is not rigorous, and it does not necessarily mean that the word "self" should be explicitly used to induce circular references. Instead of accessing the string variable through the property self.teststr, we change the code to access it through the instance variable _teststr, as follows:

@implementation Tsetblock    -(ID) init{       if (self = [superinit]) {         self.teststr [email protected] "China";          Self.block = ^ (NSString *name,nsstring *str) {             NSLog (@ "arr:%@", _teststr);//also appears: Capturing ' self ' strongly in this Block is likely to leads to a retain cycle         };     }     returnself;  }  @end  

Can be found:
Even if "self" does not appear explicitly in your block code, a circular reference will appear! As long as you use the self-possessed thing in the block!

There are two kinds of environments to solve: do not __block under Arc, but use __weak in order to avoid circular references

1.ARC: with __week

__weaktypeof (self) weakself = self; Or

__weak SomeClass *weakself = self;


2.MRC: With __block, __block modified variables in block copy is not retain, so, can also be done to break the circular reference.
__block SomeClass *blockself = self;

Bloack retain, copy, release operations

The reference count is not changed for block retain, copy, Release Retaincount,retaincount is always 1;

Nsglobalblock:retain, copy, release operations are not valid;
Nsstackblock: Retain, release operation is not valid, it must be noted that nsstackblock after the function is returned, block memory will be recycled. Even retain is useless. The easy mistake is [[Mutableaarry Addobject:stackblock], after the function is out of the stack, the Stackblock from the Mutableaarry has been recycled and turned into a wild pointer. The correct approach is to copy the Stackblock to the heap first, then add the array: [Mutableaarry addobject:[[stackblock copy] autorelease]. A new Nsmallocblock type object is generated after Copy,copy is supported.
Nsmallocblock supports retain, release, although Retaincount is always 1, the memory manager will still increase and decrease the count. No new objects are generated after copy, only one reference is added, similar to retain;
Try not to use the retain operation on the block.

6. recursive invocation of code blocks

Code blocks want to be called recursively, the block variable must be a global variable or a static variable, so that the code block variable is initialized when the program starts, and can be called recursively

static void (^ const MYBLOCK4) (int) = ^ (int i)        {            if (i > 0)            {                NSLog (@ "%i", I);                Myblock4 (i-1);            }        };

  

Definition and use of block code blocks for IOS

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.