1 about __block variable Why can I change the value in block
1 2 3 4 5 6 7 8 9 Ten One A - - |
void foo() { __block int i = 1024 ; //此时i在栈上 int j = 1 ; //此时j在栈上 void (^blk)( void ); blk = ^{printf( "%d, %d\n" , i, j); }; //此时,blk已经初始化,它会拷贝没有__block标记的常规变量自己所持有的一块内存区,这块内存区现在位于栈上,而对于具有__block标记的变量,其地址会被拷贝置前述的内存区中 blk(); //1024, 1 void (^blkInHeap)( void ) = Block_copy(blk); //复制block后,block所持有的内存区会被拷贝至堆上,此时,我们可以说,这个block现在位于堆上 blkInHeap(); //1024,1 i++; j++; blk(); //1025,1 blkInHeap(); //1025,1 } |
Let's take a step-by-step analysis:
First, we created the variable ij on the stack, given the initial value, and then created a block variable named BLK, but not assigned a value.
Then we initialize this blk, assigned to a block with only one line of printf, it is worth noting that once a block is created, its reference to the regular variable will do the following:
A variable with no __block tag, whose value is copied to the Block private memory area
A variable with a __block tag whose address is recorded in the Block private memory area
Then call blk, print 1024, 1 well understood
Next copy Blk to heap, name Yue Blkinheap, call it, print 1024, 1 also very good understanding
Next we add value to the IJ, make it 1025 and 2, and then call Blk or BLKINHEAP, we will find the result is 1025, 1, because the variable j is already in the creation of the original block, is assigned to the block's private memory area, Subsequent operation of I is not a copy of the operation of the private memory area, when the call blk or BLKINHEAP, its printing using a copy of the private memory area, so the printing result is still 1, and the change of the variable J will take effect in real time, because the block recorded its address, through the address to visit its value, Allows the external modification of J to take effect in block.
2 about using
Reprinted from: http://fuckingblocksyntax.com/
How does I Declare A Block in objective-c?
As a
local variable:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
As a
Property:
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
As a
method Parameter:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
As an
argument to a method call:
[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];
As a
typedef:
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
Objective-c Block