我们的代码需要时刻避免循环引用的产生,如果 A 引用 B,B 又引用 A,则两个对象相互持有无法释放,造成内存泄露。但我们也可以利用这一性质实现一些特殊效果。
莫名其妙的场景需求:
生成一个匿名对象,5秒之后,自动销毁该对象。
我们知道,一个匿名对象生成之后,如果没有使用它,则该对象会被立即销毁。利用循环引用我们可以实现这一过程。
@interface MyObject : NSObject
@end
@interface MyObject ()
@property (strong, nonatomic) id hold;
@end
@implementation MyObject
- (void)dealloc {
NSLog(@"%s", __func__);
}
- (instancetype)init {
NSLog(@"%s", __func__);
if (self = [super init]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
_hold = self;
#pragma clang diagnostic pop
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)),
dispatch_get_global_queue(0, 0), ^{
_hold = nil;
});
}
return self;
}
@end
main.m:
#import "MyObject.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
[MyObject new];
});
while(1);
}
return 0;
}
Log:
2016-02-25 12:01:36.984 test[17700:813144] -[MyObject init]
2016-02-25 12:01:42.398 test[17700:813179] -[MyObject dealloc]