示例:
extern void _objc_autoreleasePoolPrint();
int main(int argc, char *argv[])
{
@autoreleasepool {
id __weak blk;
{
int a = 10;
blk = ^(NSString *msg){
NSLog(@"msg: %@", msg);
NSLog(@"%d", a);
};
}
NSLog(@"blk: %@", blk);
_objc_autoreleasePoolPrint();
((void (^)(NSString *))blk)(@"Hello!");
}
return 0;
}
输出是:
2013-05-18 13:24:10.355 __iOS_SimpleConsoleApplication[63449:c07] blk: (null)
objc[63449]: ##############
objc[63449]: AUTORELEASE POOLS for thread 0xac583a28
objc[63449]: 1 releases pending.
objc[63449]: [0x7a73000] ................ PAGE (hot) (cold)
objc[63449]: [0x7a73028] ################ POOL 0x7a73028
objc[63449]: ##############
并崩溃:)
将块分配给__weak blk变量后,它在autoreleasepool中注册,因此在离开范围后它不应该等于nil,但确实如此!为什么呢?
从blk捕获变量“a”后,我有以下输出:
2013-05-18 13:25:34.132 __iOS_SimpleConsoleApplication[63486:c07] blk: <__NSGlobalBlock__: 0x35d0>
objc[63486]: ##############
objc[63486]: AUTORELEASE POOLS for thread 0xac583a28
objc[63486]: 2 releases pending.
objc[63486]: [0x7923000] ................ PAGE (hot) (cold)
objc[63486]: [0x7923028] ################ POOL 0x7923028
objc[63486]: [0x792302c] 0x35d0 __NSGlobalBlock__
objc[63486]: ##############
2013-05-18 13:25:34.142 __iOS_SimpleConsoleApplication[63486:c07] msg: Hello!
没有任何崩溃。
答案 0 :(得分:3)
知道了!
使用没有捕获变量的块,它被添加到_NSGlobalBlock内存段,因此它的内存地址始终有效,但是当块捕获变量“a”时,它被添加到_NSStackBlock内存段,并在离开作用域后释放它。
要使用捕获的变量,我们应该使用copy方法,并且该块将被移动到_NSMallocBlock内存段。
extern void _objc_autoreleasePoolPrint();
int main(int argc, char *argv[])
{
@autoreleasepool {
id blk;
{
int a = 10;
blk = [^(NSString *msg){
NSLog(@"msg: %@", msg);
NSLog(@"a: %d", a);
} copy];
}
NSLog(@"blk: %@", blk);
_objc_autoreleasePoolPrint();
((void (^)(NSString *))blk)(@"Hello!");
}
return 0;
}
输出:
2013-05-18 13:43:51.947 __iOS_SimpleConsoleApplication[63822:c07] blk: <__NSMallocBlock__: 0x7190120>
objc[63822]: ##############
objc[63822]: AUTORELEASE POOLS for thread 0xac583a28
objc[63822]: 1 releases pending.
objc[63822]: [0x7b9f000] ................ PAGE (hot) (cold)
objc[63822]: [0x7b9f028] ################ POOL 0x7b9f028
objc[63822]: ##############
2013-05-18 13:43:51.952 __iOS_SimpleConsoleApplication[63822:c07] msg: Hello!
2013-05-18 13:43:51.952 __iOS_SimpleConsoleApplication[63822:c07] a: 10