#import "ViewController.h"
typedef void(^Block)(void);
@interface ViewController ()
@property(nonatomic,strong)Block block1;
@property(nonatomic,strong)Block block2;
@property(nonatomic,strong)NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self circularReference1];
[self circularReference2];
[self circularReference3];
[self circularReference4];
[self circularReference5];
}
#pragma mark - 必须在控制器返回前停掉计时器,打破循环引用,可正常释放
- (void)circularReference1 {
// self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(testName) userInfo:nil repeats:YES];
// [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
//上面两句等同于下面一句 scheduled会自动将timer加入主循环并自动开启计时器
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(testName) userInfo:nil repeats:YES];
}
- (void)viewDidDisappear:(BOOL)animated {
[superviewDidDisappear:animated];
[self.timer invalidate];
self.timer=nil;
}
#pragma mark - 只需将任务中的self替换成weakSelf
- (void)circularReference2 {
__weaktypeof(self) weakSelf =self;
[NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
[weakSelftestName];
}];
}
#pragma mark - 局部变量block1不会造成循环引用
- (void)circularReference3 {
Blockblock1 = ^ {
NSLog(@"= %@",self);
};
block1();
}
#pragma mark - 使用__block修饰weakSelf,但是限制条件多
- (void)circularReference4 {
__blockidweakSelf =self;
self.block1= ^ {
NSLog(@"= %@",weakSelf);
weakSelf =nil;//这里必须设置为nil,否则还是不能释放
};
self.block1();//这里必须调用,否则还是不能释放
}
#pragma mark - 使用__weak修饰weakSelf
- (void)circularReference5 {
__weaktypeof(self) weakSelf =self;
self.block2= ^ {
NSLog(@"== %@",weakSelf);
};
self.block2();
}
- (void)testName {
NSLog(@"%@",self);
}
- (void)dealloc {
NSLog(@"%s",__func__);
}
网友评论