一个奇怪的事情,和自己的推理
有如下代码
@interface AA : NSObject
@property (strong) NSString *string;
@end
@implementation AA
- (void)dealloc {
NSLog(@"%@ dealloc", self.string);
}
@end
- (void)testArcSimple {
AA * __strong aa_weak_holder = [[AA alloc] init];
AA * __weak aa_weak = aa_weak_holder;
aa_weak_holder.string = @"aa_weak";
void (^aBlock)(void) = ^(){
NSLog(@"block : %@", aa_weak.string);
};
aa_weak_holder = nil;
aBlock();}
上面的输出是:
block : aa_weak
aa_weak dealloc
而下面这段代码:
AA * __strong aa_weak_holder = [[AA alloc] init];
aa_weak_holder.string = @"weak";
AA * __weak aa_weak = aa_weak_holder;
aa_weak_holder = nil;
NSLog(@"aa : %@", aa_weak);
输出为:
weak dealloc
aa : (null)
表面看来好像是aa_weak在
void (^aBlock)(void) = ^(){
NSLog(@"block : %@", aa_weak.string);
};
的位置[[aa_weak retain] autorelease]了一遍。
自己的推断:
在程序中使用block的时候,编译器在运行时会在整个block生命周期里面为所有的block引用变量保留一个副本。虽然aa_weak_holder被指向了nil,但是由于系统为block里面引用的变量保留了一个副本,aa_weak指向的对象并没有被立即销毁,所以可以打印出对象里面的内容。
PS:以上是本人自己的理解和推断,如有误导,敬请指出。