Knowledge and use of block

Source: Internet
Author: User

Blocks is an anonymous function of objective-c. Block is the new program syntax that iOS has added after 4.0.

There are three types of blocks, _nsconcreteglobalblock,_nsconcretestackblock and _nsconcretemallocblock.

1._nsconcreteglobalblock all static blocks and does not access any external variables.

2._nsconcretestackblock The block stored in the stack, which is destroyed when the function returns.

3._nsconcretemallocblock The block stored in the heap, which is destroyed when the reference count is 0.

Replication of variables

for Block outside of the variable reference, Block The default is to copy it into its data structure for access, as shown in the image from here ):


#define TLOG (prefix,obj) {NSLog (@" variable memory address:%p, variable value:%p, Point to Object value:%@,--%@ ", &obj,obj,obj,prefix);}

The macro variables defined above are

Here's the code:

nsstring*a =@ "+";

TLog(@ "A-->non block", a);

void(^block2)(void) = ^{

TLog(@ "A-->block", a);

    };

a = @ "102";

Block2 ();

a = nil;

Block2 ();

Printing results are:

Variable memory address: 0x7fff570d3b28, variable value: 0x108b2c190, point to Object value:,--> A-->non block

Variable memory address: 0x7ff8bb533d00, variable value: 0x108b2c190, point to Object value:,--> A-->block

Variable memory address: 0x7ff8bb533d00, variable value: 0x108b2c190, point to Object value:,--> A-->block

indicates that the external variable is Copy to the Block The changes in the outside variables do not cause Block changes in the variable. Two is not the same variable. The external variable cannot be modified in the block at the same time .

__weak Modify the code as follows:

__weak nsstring *b =@ "123";

TLog(@ "B-->non block", b);

void(^blocka) (void) = ^{

TLog(@ "C-->block", b);

    };

Blocka ();

B = nil;

TLog(@ "b-->1", b);

Blocka ();

The printing results are as follows:

Variable memory address: 0x7fff57ddcb28, variable value: 0x107e23190, point to Object value: 123,--> B-->non block

Variable memory address: 0X7FB95AE2DD10, variable value: 0x107e23190, point to Object value: 123,--> C-->block

Variable memory address: 0x7fff57ddcb28, variable value: 0x0, point to Object value: (null),--> B-->1

Variable memory address: 0X7FB95AE2DD10, variable value: 0x107e23190, point to Object value: 123,--> C-->block

__weak Retouching, Entire content Copy , so B = Nil , does not affect the Block Internal.

for use with __block the modified external variable reference, Block is to replicate its reference address for access, as shown in the image from here ):


__block nsstring*a =@ "+";

TLog(@ "A-->non block", a);

void(^block2) (void) = ^{

TLog(@ "A-->block", a);

    };

a = @ "102";

Block2 ();

a = nil;

Block2 ();

Printing results are:

Variable memory address: 0x7fff54e04b28, variable value: 0x10adfb1a0, point to Object value:,--> A-->non block

Variable memory address: 0x7ff52a604078, variable value: 0x10adfb220, point to Object value: 102,--> A-->block

Variable memory address: 0x7ff52a604078, variable value: 0x0, point to Object value: (null),--> A-->block

with __block A modified variable, just a pointer to the Copy , so when an external variable is modified, it also affects the Block the internal changes. the same effect as the static modifier. External variables can be modified inside the block.

How to avoid block circular references

nsstring *a = [[nsstringalloc]initwithformat:@ "%d" ,123];

TLog(@ "A", a);

__weaknsstring *b = a;//b Just makes a pointer copy, so A's value change also affects B. At the same time a release, B also released.

TLog(@ "B-->non block", b);

void(^blocka) (void) = ^{

TLog(@ "B-->block", b);

    };

  

Blocka ();

a = nil;

Blocka ();

The printing results are as follows:

Variable memory address: 0x7fff53db5b28, variable value: 0x7fd4b8f1a210, point to Object value: 123,--> A

Variable memory address: 0X7FFF53DB5B20, variable value: 0x7fd4b8f1a210, point to Object value: 123,--> B-->non block

Variable memory address: 0X7FD4B8F17B50, variable value: 0x7fd4b8f1a210, point to Object value: 123,--> B-->block

Variable memory address: 0X7FD4B8F17B50, variable value: 0x0, point to Object value: (null),--> B-->block

From the above results can be seen

· B and External B in block are not the same variable (content copy)

· block captures B as well as a weak reference to a, and when I release a from the block, the variable is not read in the block.

· when A is assigned nil, the B inside the block is also nil, that is, A is actually released, so the __weak can avoid circular referencing .

· the __weak itself is a problem that avoids circular references, but it can cause external objects to be freed,and the block will not be able to access this object internally, and we can declare a __ within the block. Strong variables to point to weakobj, allowing external objects to both hold inside the block and to avoid circular referencing problems

· and using __block

MyObject*obj = [MyObjectnew];

obj.text=@ "123456";

TLog(@ "obj", obj);

__blockMyObject*weakobj= obj;

TLog(@ "Weakobj-->non block", weakobj);

void(^block2) (void) = ^{

TLog(@ "Weakobj-->block", weakobj);

    };

Block2 ();

obj = nil;

· Block2 ();

· The printing results are as follows:

Variable memory address: 0x7fff5d723b28, variable value: 0X7FF999C990E0, point to Object value: <myobject:0x7ff999c990e0>,--obj

Variable memory address: 0X7FFF5D723B20, variable value: 0X7FF999C990E0, point to Object value: <myobject:0x7ff999c990e0>,--Weakobj-->non block

Variable memory address: 0x7ff999e3f098, variable value: 0X7FF999C990E0, point to Object value: <myobject:0x7ff999c990e0>,--Weakobj-->block

Variable memory address: 0x7ff999e3f098, variable value: 0X7FF999C990E0, point to Object value: <myobject:0x7ff999c990e0>,--Weakobj-->block

when the external When obj points to nil, obj is supposed to be released, but in fact Blockobj still strongly cites obj,obj and is not actually released. Therefore, using __block does not avoid the problem of circular references.

__block the problem of circular references cannot be avoided by itself, but we can avoid circular references by manually assigning the blockobj to nil within the block. Another point is that __block modified variables are unique inside and outside the block, so be aware of the potential pitfalls of this feature.


Reference Linkshttp://blog.devtang.com/blog/2013/07/28/a-look-inside-blocks/ http://honglu.me/2015/01/06/weak%E4%B8%8Eblock%E5%8C%BA%E5%88%AB/

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Knowledge and use of block

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.