Understanding and use of Block

Source: Internet
Author: User

Understanding and use of Block

Blocks is an anonymous function of Objective-C. Block is the program syntax added after iOS 4.0.

Blocks has three types: _ NSConcreteGlobalBlock, _ NSConcreteStackBlock, and _ NSConcreteMallocBlock.

1. _ NSConcreteGlobalBlock: All static blocks do not access any external variables.

2. _ NSConcreteStackBlock the block stored in the stack will be destroyed when the function returns.

3. _ NSConcreteMallocBlock: The block stored in the heap is destroyed when the reference count is 0.

Variable Replication

For variable references outside the block, the block is copied to its data structure by default for access, as shown in (picture from here ):


# Define TLog (prefix, Obj) {NSLog (@ "variable memory address: % p, variable value: % p, pointing to object Value: % @, --> % @", & Obj, prefix );}

Macro variables defined above

The following code is used:

NSString * a = @" 100 ";

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

Void (^ block2) (void) = ^ {

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

};

A = @ "102 ";

Block2 ();

A = nil;

Block2 ();

The output is as follows:

Variable memory address: 0x7fff570d3b28, variable value: 0x0000b2c190, pointing to object Value: 100, --> a --> non block

Variable memory address: 0x7ff8bb533d00, variable value: 0x0000b2c190, pointing to object Value: 100, --> a --> block

Variable memory address: 0x7ff8bb533d00, variable value: 0x0000b2c190, pointing to object Value: 100, --> a --> block

This indicates that the external variables are copied to the block. Changes in the external variables will not cause changes in the block. The two are not the same variables. At the same time, external variables cannot be modified in the block.

_ Weak:

_ 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 output is as follows:

Variable memory address: 0x7fff57ddcb28, variable value: 0x0000e23190, pointing to object Value: 123, --> B --> non block

Variable memory address: 0x7fb95ae2dd10, variable value: 0x0000e23190, pointing to object Value: 123, --> c --> block

Variable memory address: 0x7fff57ddcb28, variable value: 0x0, pointing to object Value: (null), --> B --> 1

Variable memory address: 0x7fb95ae2dd10, variable value: 0x0000e23190, pointing to object Value: 123, --> c --> block

_ Weak modifier. The entire content is copied. Therefore, B = nil does not affect the block.

 

For external variable references modified with _ block, block copies its reference address for access, as shown in (picture from here ):


_ BlockNSString * a = @ "100 ";

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

Void (^ block2) (void) = ^ {

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

};

A = @ "102 ";

Block2 ();

A = nil;

Block2 ();

The output is as follows:

Variable memory address: 0x7fff54e04b28, variable value: 0x10adfb1a0, pointing to object Value: 100, --> a --> non block

Variable memory address: 0x7ff52a604078, variable value: 0x10adfb220, pointing to object Value: 102, --> a --> block

Variable memory address: 0x7ff52a604078, variable value: 0x0, pointing to object Value: (null), --> a --> block

Variables modified with _ block are just pointer copies. Therefore, modifications to external variables also affect internal changes in the block. The effect is the same as that of static modification. You can modify external variables within the block.

How to Avoid block reference

NSString * a = [[NSStringalloc] initWithFormat: @ "% d", 123];

TLog (@ "a", );

_ WeakNSString * B = a; // B only performs the copy of the pointer to a, so the value change of a also affects B. At the same time, when a is released, B is also released.

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

Void (^ blocka) (void) = ^ {

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

};

Blocka ();

A = nil;

Blocka ();

The output is as follows:

Variable memory address: 0x7fff53db5b28, variable value: 0x7fd4b8f1a210, pointing to object Value: 123, -->

Variable memory address: 0x7fff53db5b20, variable value: 0x7fd4b8f1a210, pointing to object Value: 123, --> B --> non block

Variable memory address: 0x7fd4b8f17b50, variable value: 0x7fd4b8f1a210, pointing to object Value: 123, --> B --> block

Variable memory address: 0x7fd4b8f17b50, variable value: 0x0, pointing to object Value: (null), --> B --> block

As shown in the preceding result

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

· Block captures B and also provides weak references to a. When I release a outside the block, the variable cannot be read in the block.

· When a is assigned a value to nil, B in the block is also nil. That is to say, a is actually released. It can be seen that _ weak can avoid the issue of circular reference.

· _ Weak itself can avoid the problem of circular reference, but it will cause the problem that the block cannot access this object after the external object is released, we can declare a _ strong variable inside the block to point to weakObj, so that the external object can be kept inside the block and avoid the issue of circular reference.

· Use _ 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 printed result is as follows:

Variable memory address: 0x7fff5d723b28, variable value: 0x7ff999c990e0, pointing to object Value: <MyObject: 0x7ff999c990e0>, --> obj

Variable memory address: 0x7fff5d723b20, variable value: 0x7ff999c990e0, pointing to object Value: <MyObject: 0x7ff999c990e0>, --> weakObj --> non block

Variable memory address: 0x7ff999e3f098, variable value: 0x7ff999c990e0, pointing to object Value: <MyObject: 0x7ff999c990e0>, --> weakObj --> block

Variable memory address: 0x7ff999e3f098, variable value: 0x7ff999c990e0, pointing to object Value: <MyObject: 0x7ff999c990e0>, --> weakObj --> block

When the external obj points to nil, The obj should be released, but in fact blockObj still strongly references obj, which is not actually released. Therefore, the use of _ block cannot avoid the issue of circular reference.

_ Block itself cannot avoid the issue of loop reference, but we can avoid the issue of loop reference by manually assigning blockObj to nil inside the block. Another point is that the variable modified by _ block is unique inside and outside the block. Pay attention to the potential risks caused by this feature.


Reference http://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 Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

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.