[英]iOS - GCD and __strong reference
我有這段代碼,我想做的是在將要在主線程上執行的代碼塊中保持活動狀態。 結果是隨機的,有時會顯示null。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.proArray = [[NSMutableArray alloc]init];
GCDVC2* __weak weakSelf = self;
self.postGCDBlock = ^{
GCDVC2* __strong strongSelf2 = weakSelf;
[strongSelf2.proArray removeObject:@"3"];
NSLog(@"%@",strongSelf2.proArray);
[strongSelf2.activityIndicator stopAnimating];
};
self.addObjectsBlock = ^{
GCDVC2* __strong strongSelf = weakSelf;
[strongSelf.proArray addObject:@"2"];
[strongSelf.proArray addObject:@"3"];
[NSThread sleepForTimeInterval:5];
dispatch_async(dispatch_get_main_queue(),strongSelf.postGCDBlock);
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), self.addObjectsBlock);
}
這段代碼可以正常工作:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.proArray = [[NSMutableArray alloc]init];
GCDVC2* __weak weakSelf = self;
//self.postGCDBlock = ;
self.addObjectsBlock = ^{
GCDVC2* __strong strongSelf = weakSelf;
[strongSelf.proArray addObject:@"2"];
[strongSelf.proArray addObject:@"3"];
[NSThread sleepForTimeInterval:5];
GCDVC2* __weak weakSelf2 = strongSelf;
dispatch_async(dispatch_get_main_queue(),^{
GCDVC2* __strong strongSelf = weakSelf2;
[strongSelf.proArray removeObject:@"3"];
NSLog(@"%@",strongSelf.proArray);
[strongSelf.activityIndicator stopAnimating];
});
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), self.addObjectsBlock);
}
有什么方法可以轉換第二段代碼以使其與第一段代碼的結構一起使用? 我嘗試了很多變體,但總是隨機的。 我可以以某種方式確保self.postGCDBlock不會使self為零嗎?
更新:屬性聲明:
typedef void(^CustomBlock)(void);
@interface GCDVC2 ()
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
@property(nonatomic,strong)NSMutableArray *proArray;
@property (nonatomic, copy) CustomBlock addObjectsBlock;
@property (nonatomic, copy) CustomBlock postGCDBlock;
@end
我認為您的問題出在這一行(我無法使用此代碼重現失敗案例):
dispatch_async(dispatch_get_main_queue(),strongSelf.postGCDBlock);
此時,在您的addObjectsBlock
, strongSelf
持有對self
的引用,但是當您離開該塊的范圍時結束。 dispatch_async
將復制postGCDBlock
,但是該塊沒有對self
的強烈引用。
為了使dispatch_async
擁有對self
的強大引用,您需要執行以下操作:
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.postGCDBlock();
});
在代碼塊中包裝strongSelf
會導致dispatch_async
保留strongSelf
(並因此將self
)保留足夠長的時間,以使其調用postGCDBlock
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.