我們新建一個(gè)NewViewController
,在開始的ViewController
寫如下代碼
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 100, 50);
btn.backgroundColor = [UIColor brownColor];
[btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)jump{
NewViewController *newVC = [[NewViewController alloc]init];
[self presentViewController:newVC animated:YES completion:nil];
}
然后在NewViewController
里:
-(void)dealloc{
NSLog(@"--------------dealloc");
}
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 300, 100, 50);
btn.backgroundColor = [UIColor brownColor];
[btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self log];
NSLog(@"--------------after");
});
}
-(void)log{
NSLog(@"--------------log");
}
-(void)jump{
NSLog(@"--------------dismiss");
[self dismissViewControllerAnimated:YES completion:nil];
}
運(yùn)行之后骇吭,我們一跳進(jìn)newVC里面返回怖糊,這時(shí)候:
image.png
結(jié)果說明我們dismiss的時(shí)候吁恍,newVC還沒有被釋放悬钳,
dealloc
方法在dispatch_after
延遲方法執(zhí)行之后才會(huì)走塞蹭,原因就是dispatch_after
強(qiáng)引用了self(即newVC)
匹表,等強(qiáng)引用過去门坷,self
才能得到釋放走dealloc
。
接下來袍镀,我們?cè)?code>dispatch_after里把 self 用 __weak
修飾默蚌,block里把self
改為weakself
,我們還是一樣的操作流程,看看結(jié)果:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 300, 100, 50);
btn.backgroundColor = [UIColor brownColor];
[btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf log];
NSLog(@"--------------after");
});
}
image.png
當(dāng)我們用weak修飾self時(shí)流椒,
dispatch_after
并沒有強(qiáng)引用self
,所以我們dissmiss
時(shí)敏簿,dealloc
立馬就會(huì)走,然后10s后宣虾,dispatch_after
的執(zhí)行函數(shù)還是會(huì)執(zhí)行惯裕,輸出了after,但是沒有輸出log绣硝,這是因?yàn)橛玫?code>weakSelf蜻势,dissmiss
后,newVC已經(jīng)被釋放鹉胖,這時(shí)候代碼 [weakSelf log];
等同于[nil log];
握玛,所以才不會(huì)輸出log。
使用注意
雖然dispatch_after
里直接調(diào)用self
不會(huì)造成循環(huán)引用甫菠,但當(dāng)我們dispatch_after
延遲時(shí)間過長的時(shí)候挠铲,需要考慮是否要及時(shí)釋放當(dāng)前對(duì)象,如果需要寂诱,盡量使用weakSelf
這種方式,如果真有需要用到self完成一些操作再釋放的需求拂苹,可以按需編寫代碼。