Reputation: 17677
With the following code:
@interface MyClass()
{
NSMutableArray * dataArray;
}
@end
@implementation MyClass
- (void) doSomething
{
__typeof__(self) __weak wself = self;
dispatch_async(dispatch_get_global_queue(0,0), ^{
__typeof__(self) sself = wself;
[sself->dataArray addObject: @"Hello World"];
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 30];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: sself->dataArray[0]
message: @"Message"
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alert show];
});
});
}
@end
sself
from within the main queue block?sself
go out of scope once the initial queue finished?__typeof__(self) sself = wself;
inside the main queue block?Upvotes: 3
Views: 636
Reputation: 437622
You ask:
Is this the proper way to access
sself
from within the main queue block?
Almost. You also should be checking to make sure sself
is not nil
, too. You do this because dereferencing a ivar for an nil
pointer may crash your app. Thus, check to make sure it's not nil
:
- (void) doSomething
{
typeof(self) __weak wself = self;
dispatch_async(dispatch_get_global_queue(0,0), ^{
typeof(self) sself = wself;
if (sself) {
[sself->dataArray addObject: @"Hello World"];
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 30];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: sself->dataArray[0]
message: @"Message"
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alert show];
});
}
});
}
You then ask:
Would
sself
go out of scope once the initial queue finished?
It goes out of scope, but is retained by the inner block and will be retained until that inner block finishes.
Should I add a second
__typeof__(self) sself = wself;
inside the main queue block?
You can if you want to, but it's not necessary. It depends upon the desired behavior. If, for example, you want to see this alert even if the current object (presumably a view controller) is dismissed, then use sself
pattern (because you presumably want to hang on to it so you have access to dataArray
). If you don't want to show the alert anymore, then you'd repeat this weakSelf
/strongSelf
dance.
Upvotes: 1
Reputation: 1225
__typeof__(self) sself = wself;
even in global_queue block; it's not necessary, you already have a weakened self object wself
(moreover, you will retain self
in __typeof__(self)
part inside the block).__typeof__
. Use simply typeof(self)
Upvotes: 2