This is what I have learned: when using self
retained block
weakSelf
to break retain cycle strongSelf
to prevent self
from becoming nil half-way so I want to test if a strongSelf
can really keep self
alive like so:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"viewDidLoad");
self.test = @"test";
NSLog(@"%@",self.test);
__weak typeof(self)weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong typeof(weakSelf)strongSelf = weakSelf;
strongSelf.test = @"newTest";
NSLog(@"%@",strongSelf.test);
});
}
- (void)dealloc {
NSLog(@"dealloc");
}
@end
The ViewController will be pushed into a navigationController and pop out immediately. The output is
why the null?
There is another question I have a project which contains tons of weakSelf
without strongSelf
in the block and I get plenty of signal 11 crash. Is it related? Is it worth to add strongSelf
to each of them?
strongSelf
ensures that if self
was not released yet, it won't during the execution of the block.
If the self is gone before you create strongSelf
, it will be nil.
You should check, if strongSelf
does contain something:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
typeof(weakSelf)strongSelf = weakSelf; // __strong is not needed
if(strongSelf){
strongSelf.test = @"newTest";
NSLog(@"%@",strongSelf.test);
}
});
The code in your block is executed after 3s delay. So by this time the weakSelf is already nil. That's why strongSelf is nil
I think you don't hit the problem right. Using weakself will break the retain cycle, however this line:
__strong typeof(weakSelf)strongSelf = weakSelf;
Does not capture strong reference to self until block is executed. Hence if your pointer to VC outside of block is nil, VC will be released and weakSelf will be nil when you hit the block - meaning your strongSelf will be nil also. Capturing strong reference guarantee only that if you have weak self at the begin of the block, you will have it until the end and it won't be dealloc meanwhile. However if weakSelf is nil at begin of the block - strongSelf will be nil also. Moreover you do not need to declare it as strong inside block, as it will be strong by definition, hence it could be replaced by:
typeof(weakSelf)strongSelf = weakSelf;
or
id strongSelf = weakSelf;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.