当捕获__strong
变量的Block被复制到堆中时,该变量也会被复制到具有_block_copy()
函数的堆中。
但是使用__weak
变量会发生什么?
id __weak weakObj = someObj;
someBlock = [^() {
//using __weak variable
} copy];
答案 0 :(得分:0)
当一个块捕获任何非__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管理的指针类型仍然如此无论是强者还是弱者。
答案 1 :(得分:-2)
我试过这个:
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
<强>结论:强>
在块内,弱对象的内存地址被更改。因此,弱对象被复制到堆中。并且可以使用__block_copy()函数。
在块外,弱对象在复制后保留原始内存地址。