簡體   English   中英

iOS-GCD和__strong參考

[英]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);

此時,在您的addObjectsBlockstrongSelf持有對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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM