Objective-C iOS Block: objective-cios

Source: Internet
Author: User

Objective-C iOS Block: objective-cios

Before learning about Block, we need to first understand some basic knowledge.
We all know that Objective-C is extended by C language. In Objective-C, a reference is a pointer to an object. That is, the reference is a variable, a pointer, and the address of the object is stored. Therefore, the reference itself actually has an address. Therefore, the objects referenced and referenced are two different concepts.
1. In Objective-C, references are generally divided into strong and weak reference types. That is, references modified by _ strong and _ weak. If the reference type is not explicitly specified, the default value is _ strong. A strong reference will add 1 to the reference count of the object to be pointed to, while a weak reference will not, and the weak reference will be set to nil when the object to be pointed to is released.
2. The Block is divided into two states: defined and running. During definition, Block blocks are compiled as classes and Block blocks are created as objects (the Block code is equivalent to the object method). At this time, Block blocks are not running. The runtime refers to the execution of Block code. (This concept is defined to understand Block and is not officially defined .)
3. A non-local reference refers to a local reference defined outside the Block, but has the scope of this reference in the Block.
After learning about the basic knowledge, we can start to learn more about Block. This article mainly studies the correct use of Block, and why it should be used in this way, without a deep understanding of the implementation principle of Block.
First, when using non-local references in a Block, let's take a look at the following example:

    NSString *string = @"Smith";        void(^block)() = ^(){        NSLog(@"%@",string);    };        string = @"Jackyson";    block();

We know that the running result is Smith. So why? We can try to print the address referenced by string. Note that the address referenced by string is not the address of the object pointed to by string. The two are very different. The following example is used:

NSString * string = @ "Smith"; NSLog (@ "1 ----- string object: % @, string reference address: % p", string, & string ); void (^ block) () = ^ () {NSLog (@ "3 ----- string object: % @, string reference address: % p", string, & string) ;}; string = @ "Jackyson"; NSLog (@ "2 ----- string object: % @, string reference address: % p", string, & string ); block ();

The following is my running result:

16:43:23. 179 Block [73629: 3669954] 1 ----- string object: Smith, string reference address: 0x7fff5e6f3a182016-09-11 16:43:23. 179 Block [73629: 3669954] 2 ----- string object: Jackyson, string reference address: 0x7fff5e6f3a182016-09-11 16:43:23. 180 Block [73629: 3669954] 3 ----- string object: Smith, string reference address: 0x7fca60c37260

From the above we can see that the strings defined inside the Block are different from those defined outside the Block. They are two different references, it only points to the string object "Smith.
In fact, when a Block accesses an external object through a non-local reference, because the non-local reference will expire at the end of the current scope (the external object will be recycled ), to ensure that the Block can correctly access external objects during real operation, a non-local reference (member variable) is replicated within the Block during Block definition ). When non-local references are modified using _ block, internal references are const-modified references, which means that the value of internal references cannot be changed (cannot point to new objects ). If the _ block modifier is not used, the internal reference does not have a const modifier reference, which means that the internal reference value can be changed (which can point to a new object ). In addition, internal references and non-local references are of the same strength type.
Let's go back to the above example and access the "Smith" object through string in the Block. When the Block is defined, an internal reference with the name of string is automatically generated (the scope is within the Block), and the value of this pointer cannot be modified (const), that is, the reference cannot point to a new object, therefore, the internal reference string always points to the string "Smith ". Instead of local reference, the string points to the New string object "Jackyson", which has no relationship with the internal reference string. Therefore, it is equivalent to copying the "Smith" string to the Block and cannot be modified.
So what should we do if we want internal references to point to new objects, or if we want to modify the reference values inside and outside the Block to affect each other? The answer is to use _ block to modify the reference. The code example is as follows:

_ Block NSString * string = @ "Smith"; NSLog (@ "1 ----- string object: % @, string reference address: % p", string, & string ); void (^ block) () = ^ () {NSLog (@ "3 ----- string object: % @, string reference address: % p", string, & string ); string = @ "SmithJackyson"; NSLog (@ "4 ----- string object: % @, string reference address: % p", string, & string );}; string = @ "Jackyson"; NSLog (@ "2 ----- string object: % @, string reference address: % p", string, & string); block (); NSLog (@ "5 ----- string object: % @, string reference address: % p", string, & string );

The following is my running result:

17:15:33. 063 Block [74333: 3683201] 1 ----- string object: Smith, string reference address: 0x7fff5510aa182016-09-11 17:15:33. 066 Block [74333: 3683201] 2 ----- string object: Jackyson, string reference address: 0x7fb351c1fb082016-09-11 17:15:33. 066 Block [74333: 3683201] 3 ----- string object: Jackyson, string reference address: 0x7fb351c1fb082016-09-11 17:15:33. 067 Block [74333: 3683201] 4 ----- string object: SmithJackyson, string reference address: 0x7fb351c1fb0817:15:33. 068 Block [74333: 3683201] 5 ----- string object: SmithJackyson, string reference address: 0x7fb351c1fb08

Here, I make a hypothesis about the influence of the _ block modifier:
Whether to use the _ block modifier for non-local references will affect the access modifier for internal references. Because the Block can also be used as an object, when the _ block modifier is not used, the internal reference is a member variable modified by @ protected or @ private. When _ block is used for modification, the internal reference is a member variable modified by @ public.
This assumption can better explain why modifying the reference value inside and outside the block Block can affect each other after _ block is used. If you have a better explanation, please share it with me !!!
From the result analysis, we can use _ block to modify the string reference. when defining a Block, we define an internal reference string (@ public modified member variable) in the Block ). Why does string point to the "Jackyson" string object affect the string value in the Block? After the Block is defined, the compiler processes the strings used after the Block is defined. The string is used to access the internal reference string in the Block block (similar to Block-> string ), so string points to the string "Jackyson", which means to point the string in the Block to the string "Jackyson ". Similarly, to point a string to the string "SmithJackyson" in a Block means to point a string outside the Block to the string "SmithJackyson ".
Therefore, after _ block modifies a reference, changing the reference values inside or outside the Block will affect each other because they are the same reference.
In addition, for the use of member variables in Block blocks, let's take a look at the following example:

@ Interface ViewController () {NSString * _ string;} @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; _ string = @ "Smith "; NSLog (@ "1 ----- string object: % @, string reference address: % p", _ string, & _ string ); NSLog (@ "1 ****** address referenced by self: % p", & self); void (^ block) () = ^ () {NSLog (@ "3 ----- string object: % @, string reference address: % p", _ string, & _ string ); NSLog (@ "3 ***** address referenced by self: % p", & self); _ string = @ "SmithJackyson"; NSLog (@ "4 ----- string object: % @, string reference address: % p ", _ string, & _ string); NSLog (@" 4 ***** self reference address: % p ", & self) ;}; _ string = @ "Jackyson"; NSLog (@ "2 ----- string object: % @, string reference address: % p", _ string, & _ string); NSLog (@ "2 ***** address referenced by self: % p", & self); block (); NSLog (@ "5 ----- string object: % @, string reference address: % p", _ string, & _ string ); NSLog (@ "5 ***** address referenced by self: % p", & self) ;}@ end

The following is my running result:

17:37:11. 162 Block [98324: 4200964] 1 ----- string object: Smith, string reference address: 0x7f90b0cf928017:37:11. 162 Block [98324: 4200964] 1 ***** address referenced by self: 0x7fff57817a282016-09-13 17:37:11. 163 Block [98324: 4200964] 2 ----- string object: Jackyson, string reference address: 0x7f90b0cf928017:37:11. 163 Block [98324: 4200964] 2 ***** address referenced by self: 0x7fff57817a282016-09-13 17:37:11. 163 Block [98324: 4200964] 3 ----- string object: Jackyson, string reference address: 0x7f90b0cf928017:37:11. 163 Block [98324: 4200964] 3 ***** address referenced by self: 0x7f90b0d86fb02016-09-13 17:37:11. 163 Block [98324: 4200964] 4 ----- string object: SmithJackyson, string reference address: 0x7f90b0cf92802016-09-13 17:37:11. 163 Block [98324: 4200964] 4 ***** address referenced by self: 0x7f90b0d86fb02016-09-13 17:37:11. 163 Block [98324: 4200964] 5 ----- string object: SmithJackyson, string reference address: 0x7f90b0cf92802016-09-13 17:37:11. 163 Block [98324: 4200964] 5 ***** address referenced by self: 0x7fff57817a28

From the results, we can see that the _ string reference used in the Block is the member Variable _ string, because the Block actually uses self-> _ string to access the member Variable _ string, therefore, the Block defines the internal reference of self and uses the internal reference of self-> _ string to access the member Variable _ string. Therefore, the _ string and _ string references in the Block are the same, and changing the reference values inside and outside the Block will affect each other.
After analyzing the effect of the _ block modifier, Let's see why _ strong and _ weak can avoid circular references?
As we have learned before, when a Block accesses an external object through external references, when the Block is defined, an internal reference is copied to the external reference definition, the internal reference strength type is consistent with that of the external reference. When the object itself has a member variable holding a Block, and the Block accesses the object itself, it may cause circular reference. Here we use UIViewController as an example, for example:

When a Block accesses an external object through external references, an internal reference with the same strong and weak types is copied during Block definition. If the external reference is modified using _ block, the internal reference is variable, that is, it can point to a new object, and the access modifier is @ public, that is, after the Block block is defined, instead of external references, internal references are used through Block-> _ internalReference. If the _ block modifier is not used, the internal reference is immutable, that is, it cannot point to a new object, and the access modifier is @ protected or @ private, that is, after Block definition, external references are used and there is no connection with internal references. They do not affect each other.

 

 

Reprinted Please note: Author SmithJackyson

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.