我是否需要块中的 strongSelf 来保持 self 存活并且 strongSelf 真的有效吗?
Do I need a strongSelf in block to keep self alive and does the strongSelf really work?
这是我学到的:使用self
保留块时
- 我需要一个
weakSelf
来打破保留周期
- 我需要一个
strongSelf
来防止self
中途变成nil
所以我想测试一下 strongSelf
是否真的可以像这样让 self
活着:
@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
ViewController 将被推入 navigationController 并立即弹出。输出是
为什么为空?
还有一个问题,我有一个项目包含大量 weakSelf
而块中没有 strongSelf
,并且我收到大量信号 11 崩溃。有关系吗?是否值得为每个添加 strongSelf
?
strongSelf
确保如果 self
尚未释放,则不会在块执行期间释放。
如果在你创建之前self已经消失了strongSelf
,它将是nil。
你应该检查一下,如果 strongSelf
确实包含某些东西:
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);
}
});
你的块中的代码在延迟 3 秒后执行。所以此时 weakSelf 已经为零。这就是为什么 strongSelf 是 nil
我认为你没有找到正确的问题。使用 weakself 会打破保留周期,但是这一行:
__strong typeof(weakSelf)strongSelf = weakSelf;
在执行块之前不捕获对自身的强引用。因此,如果您指向块外 VC 的指针为 nil,则 VC 将被释放,并且当您击中块时 weakSelf 将为 nil - 这意味着您的 strongSelf 也将为 nil。捕获强引用只保证如果你在块的开头有 weak self,你将拥有它直到结束并且它不会同时被释放。但是,如果 weakSelf 在块的开头为 nil - strongSelf 也将为 nil。此外,您不需要在块内将其声明为 strong ,因为根据定义它将是 strong ,因此可以将其替换为:
typeof(weakSelf)strongSelf = weakSelf;
或
id strongSelf = weakSelf;
这是我学到的:使用self
保留块时
- 我需要一个
weakSelf
来打破保留周期 - 我需要一个
strongSelf
来防止self
中途变成nil
所以我想测试一下 strongSelf
是否真的可以像这样让 self
活着:
@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
ViewController 将被推入 navigationController 并立即弹出。输出是
为什么为空?
还有一个问题,我有一个项目包含大量 weakSelf
而块中没有 strongSelf
,并且我收到大量信号 11 崩溃。有关系吗?是否值得为每个添加 strongSelf
?
strongSelf
确保如果 self
尚未释放,则不会在块执行期间释放。
如果在你创建之前self已经消失了strongSelf
,它将是nil。
你应该检查一下,如果 strongSelf
确实包含某些东西:
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);
}
});
你的块中的代码在延迟 3 秒后执行。所以此时 weakSelf 已经为零。这就是为什么 strongSelf 是 nil
我认为你没有找到正确的问题。使用 weakself 会打破保留周期,但是这一行:
__strong typeof(weakSelf)strongSelf = weakSelf;
在执行块之前不捕获对自身的强引用。因此,如果您指向块外 VC 的指针为 nil,则 VC 将被释放,并且当您击中块时 weakSelf 将为 nil - 这意味着您的 strongSelf 也将为 nil。捕获强引用只保证如果你在块的开头有 weak self,你将拥有它直到结束并且它不会同时被释放。但是,如果 weakSelf 在块的开头为 nil - strongSelf 也将为 nil。此外,您不需要在块内将其声明为 strong ,因为根据定义它将是 strong ,因此可以将其替换为:
typeof(weakSelf)strongSelf = weakSelf;
或
id strongSelf = weakSelf;