使用_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
结论:
块内,弱对象的MEMOR y地址被改变。所以,弱对象被复制到堆中。并且可以使用__block_copy()函数。
在块外部,弱对象在复制后保留原始内存地址。
答
当一个块捕获任何非__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管理的指针类型(强和弱)仍然同样如此。