2016-07-29 52 views
0

我有这个代码,我想要做的就是保持自己活跃在块中,它将在主线程上执行。结果是一种随机的,有时打印空。iOS - GCD和__strong的参考

- (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不会有自我为零吗?

更新: 财产申报:

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 
+0

属性声明如何在视图控制器中看起来像? –

+0

更新了答案! – BlackM

回答

3

我认为(我不能重现故障情况下使用此代码)您的问题在于这一行:

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

+0

解决了这个问题。我认为通过使用'strongSelf.postGCDBlock'作为参数,它会保留strongSelf – BlackM