使用_block_copy()函数将捕获的__weak变量复制到堆?

问题描述:

当一个块捕获一个__strong变量被复制到堆中时,该变量也会被复制到具有_block_copy()函数的堆中。使用_block_copy()函数将捕获的__weak变量复制到堆?

但使用__weak变量会发生什么情况?

id __weak weakObj = someObj; 
someBlock = [^() { 
    //using __weak variable 
} copy]; 

我已经试过这样:

NSNumber *testNumber = [[NSNumber alloc] initWithInt:5]; 

NSNumber *__weak weakObj = testNumber; 
NSLog(@"original weakObj address = %p",&weakObj); 

id someBlock = [^() { 
    NSLog(@"value in block:%ld",(long)weakObj.integerValue); 
    NSLog(@"weakObj address inside block = %p",&weakObj); 
} copy]; 

testNumber = [[NSNumber alloc] initWithInt:6]; 
NSLog(@"value outside:%ld",(long)testNumber.integerValue); 

[someBlock invoke]; 

NSLog(@"weakObj address = %p",&weakObj); 

结果是:

original weakObj address = 0x7fff5fbff750 
value outside:6 
value in block:5 
weakObj address inside block = 0x1005023f0 
weakObj address = 0x7fff5fbff750 

结论:

  1. 块内,弱对象的MEMOR y地址被改变。所以,弱对象被复制到堆中。并且可以使用__block_copy()函数。

  2. 在块外部,弱对象在复制后保留原始内存地址。

当一个块捕获任何非__block变量,创建,而不是当该块被复制的块时,变量始终复制到保持与所述块一个独立的副本。即使该块是而不是移到堆中也是如此。无论变量的类型如何(无论是原始类型还是ARC管理的强指针类型或弱指针类型),情况也是如此。

例如,如果您运行ARC下面的例子关闭:

int foo = 5; 
void (^someBlock)(void) = ^{ 
    NSLog(@"value in block: %d", foo); 
}; 
foo = 6; 
NSLog(@"value outside block: %d", foo); // logs "value outside block: 6" 
someBlock();       // logs "value in block: 5" 
NSLog(@"block is: %@", someBlock);  // logs "block is: <__NSStackBlock__: 0x7fff523f0ba0>" 

你会发现,该块从未移到堆的,因为它在末端为__NSStackBlock__(我做到了因为ARC可能会将块隐式移动到堆的防御方式,所以ARC关闭后可以控制块的复制。您还会注意到,块内部变量的值不受在块创建之后对块外变量的赋值的影响,这证明变量在赋值之前(即块创建之前)被复制。这个演示是用原始的int来完成的,以表明它适用于任何类型 - 它不仅适用于ARC管理的指针类型 - 但对于ARC管理的指针类型(强和弱)仍然同样如此。