Below code snippet is in objective C
__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.activityIndicatorView stopAnimating];
[weakSelf.activityIndicatorView removeFromSuperview];
weakSelf.activityIndicatorView = nil;
});
weakSelf
always available/valid since it is inside the main
queue? strongSelf
only when block is other
than the main queue?Your code snippet is too small to answer on your questions fully.
weakSelf
can be both nil
or non-nil. The keyword weak
means that variable weakSelf
can become nil
in some cases. For example, if your controller has the following property:
@property (retain) MyView* myView;
In some cases you dismiss this controller and after that you call the method f
for myView
:
[self dismissViewControllerAnimated:YES completion:^{
[self.myView f];
}];
Code of the method f
is based on code snipped you provided in this question:
-(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;
});
});
}
I guess you will see in debugger that the weakSelf
will be nil
when you will try to call stopAnimating
for activityIndicatorView
. And I guess you can easily reproduce the situation when weakSelf
will be not cleared. It means that the answer on your first question is "No, the weakSelf
will be not always available/valid and the main thread does not protect you from nil
in this variable"
You need to use strongSelf
(__strong
instead of __weak
) if you don't want to loose a reference to variable inside block. For example, if in the class MyView
there is a method log
that logs some debug information:
-(void)log {
NSLog(@"LOG");
}
And if you want to log information always after the code in your code snippet will called use the following version of the method 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];
});
});
}
So, the answer, on your second question is "No, you need to use __strong
based on your application, the block can be completed in different threads".