iOS-GCD和强参考

iOS-GCD和强参考,ios,objective-c,multithreading,objective-c-blocks,Ios,Objective C,Multithreading,Objective C Blocks,我有这段代码,我试图做的是让self在块中保持活动状态,它将在主线程上执行。结果是随机的,有时打印为空 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.proArray = [[NSMutableArray alloc]init]; GCDVC2* __weak weakSelf = self; self

我有这段代码,我试图做的是让self在块中保持活动状态,它将在主线程上执行。结果是随机的,有时打印为空

- (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-to-nil吗

更新: 财产申报:

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

我认为您的问题在于这一行(我无法用此代码再现故障案例):

此时,在
addObjectsBlock
中,
strongSelf
包含对
self
的引用,但当您离开该块的范围时,该引用即告结束
dispatch\u async
将复制
postGCDBlock
,但该块不包含对
self
的强引用

要获得
dispatch\u async
以保存对
self
的强引用,您需要执行以下操作:

dispatch_async(dispatch_get_main_queue(), ^{
    strongSelf.postGCDBlock();
});

在块中包装
strongSelf
将导致
dispatch\u async
保留
strongSelf
(从而
self
)足够长的时间,以便调用
postGCDBlock

,我认为您的问题在于这一行(我无法用此代码重现故障案例):

此时,在
addObjectsBlock
中,
strongSelf
包含对
self
的引用,但当您离开该块的范围时,该引用即告结束
dispatch\u async
将复制
postGCDBlock
,但该块不包含对
self
的强引用

要获得
dispatch\u async
以保存对
self
的强引用,您需要执行以下操作:

dispatch_async(dispatch_get_main_queue(), ^{
    strongSelf.postGCDBlock();
});

在块中包装
strongSelf
将导致
dispatch\u async
保留
strongSelf
(从而
self
)足够长的时间,以便调用
postGCDBlock

视图控制器中的属性声明是什么样子?更新了答案!属性声明在视图控制器中的外观如何?更新了答案!这就解决了问题。我认为通过使用
strongSelf.postGCDBlock
作为参数,它将保留解决问题的strongSelf。我认为通过使用
strongSelf.postGCDBlock
作为参数,它将保留strongSelf