dispatch_async queue(dispatch_get_main_queue(), ^{}) 内的弱者
weakself inside dispatch_async queue(dispatch_get_main_queue(), ^{})
下面的代码片段在 objective C
__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
[weakSelf.activityIndicatorView removeFromSuperview];
weakSelf.activityIndicatorView = nil;
});
weakSelf
是否总是 available/valid 因为它在主目录中
队列?
- 只有block是other的时候才需要声明
strongSelf
比主队列?
您的代码片段太小,无法完整回答您的问题。
weakSelf
可以是 nil
或非零。关键字 weak
表示变量 weakSelf
在某些情况下可以变为 nil
。例如,如果您的控制器具有以下 属性:
@property (retain) MyView* myView;
在某些情况下,您关闭此控制器,然后为 myView
:
调用方法 f
[self dismissViewControllerAnimated:YES completion:^{
[self.myView f];
}];
方法的代码 f
基于您在此问题中提供的代码片段:
-(void)f {
[self removeFromSuperview];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
[weakSelf.activityIndicatorView removeFromSuperview];
weakSelf.activityIndicatorView = nil;
});
});
}
我猜你会在调试器中看到当你尝试为 activityIndicatorView
调用 stopAnimating
时 weakSelf
将是 nil
。而且我猜你可以很容易地重现 weakSelf
不会被清除的情况。这意味着你第一个问题的答案是 "No, the weakSelf
will be not always available/valid and the main thread does not protect you from nil
in this variable"
如果您不想丢失对块内变量的引用,则需要使用 strongSelf
(__strong
而不是 __weak
)。例如,如果 class MyView
中有一个记录一些调试信息的方法 log
:
-(void)log {
NSLog(@"LOG");
}
如果您想始终在调用代码段中的代码之后记录信息,请使用以下版本的方法 f
:
-(void)f {
[self removeFromSuperview];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
__strong MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
[weakSelf.activityIndicatorView removeFromSuperview];
weakSelf.activityIndicatorView = nil;
[weakSelf log];
});
});
}
所以,你的第二个问题的答案是 "No, you need to use __strong
based on your application, the block can be completed in different threads"。
下面的代码片段在 objective C
__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
[weakSelf.activityIndicatorView removeFromSuperview];
weakSelf.activityIndicatorView = nil;
});
weakSelf
是否总是 available/valid 因为它在主目录中 队列?- 只有block是other的时候才需要声明
strongSelf
比主队列?
您的代码片段太小,无法完整回答您的问题。
weakSelf
可以是nil
或非零。关键字weak
表示变量weakSelf
在某些情况下可以变为nil
。例如,如果您的控制器具有以下 属性:@property (retain) MyView* myView;
在某些情况下,您关闭此控制器,然后为
调用方法myView
:f
[self dismissViewControllerAnimated:YES completion:^{ [self.myView f]; }];
方法的代码
f
基于您在此问题中提供的代码片段:-(void)f { [self removeFromSuperview]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ __weak MyView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.activityIndicatorView stopAnimating]; [weakSelf.activityIndicatorView removeFromSuperview]; weakSelf.activityIndicatorView = nil; }); }); }
我猜你会在调试器中看到当你尝试为
activityIndicatorView
调用stopAnimating
时weakSelf
将是nil
。而且我猜你可以很容易地重现weakSelf
不会被清除的情况。这意味着你第一个问题的答案是 "No, theweakSelf
will be not always available/valid and the main thread does not protect you fromnil
in this variable"如果您不想丢失对块内变量的引用,则需要使用
strongSelf
(__strong
而不是__weak
)。例如,如果 classMyView
中有一个记录一些调试信息的方法log
:-(void)log { NSLog(@"LOG"); }
如果您想始终在调用代码段中的代码之后记录信息,请使用以下版本的方法
f
:-(void)f { [self removeFromSuperview]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ __strong MyView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.activityIndicatorView stopAnimating]; [weakSelf.activityIndicatorView removeFromSuperview]; weakSelf.activityIndicatorView = nil; [weakSelf log]; }); }); }
所以,你的第二个问题的答案是 "No, you need to use
__strong
based on your application, the block can be completed in different threads"。