使用以下代码:
@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
的正确方法吗?sself
是否会超出范围?__typeof__(self) sself = wself;
吗?答案 0 :(得分:2)
__typeof__(self) sself = wself;
;没有必要,你已经有一个弱化的自我对象wself
(此外,你会在块内的self
部分保留__typeof__(self)
。__typeof__
。仅使用typeof(self)
答案 1 :(得分:1)
你问:
这是从主队列块中访问
sself
的正确方法吗?
几乎。您还应该检查以确保sself
不是nil
。这样做是因为取消引用nil
指针的ivar可能会导致应用程序崩溃。因此,请检查以确保它不是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];
});
}
});
}
然后你问:
初始队列结束后,
sself
会超出范围吗?
它超出范围,但由内部块保留,并将保留直到该内部块完成。
我应该在主队列块中添加第二个
__typeof__(self) sself = wself;
吗?
如果你愿意,你可以,但没有必要。这取决于所需的行为。例如,如果您想要查看此警报,即使当前对象(可能是视图控制器)被解除,也请使用sself
模式(因为您可能希望依赖它,以便您可以访问{{ 1}})。如果您不想再显示提醒,则请重复此dataArray
/ weakSelf
舞蹈。