2016-07-29 2 views
0

나는이 코드를 가지고 있으며 내가하려고하는 것은 블록에서 자신이 살아 있는지를 메인 스레드에서 실행되도록하는 것입니다. 결과는 일종의 무작위이며 때로는 null로 인쇄됩니다.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에 자체가 없음을 보장 할 수 있습니까?

업데이트 : 재산권 선언 : 당신의 addObjectsBlock이 시점에서

dispatch_async(dispatch_get_main_queue(),strongSelf.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

나는 당신의 문제는 (이 코드와 실패 사례를 재현 할 수없는)이 라인에있다 생각 strongSelfself에 대한 참조를 보유하고 있지만 해당 블록의 범위를 벗어날 때 끝납니다. dispatch_asyncpostGCDBlock을 복사하지만 해당 블록에는 self에 대한 강력한 참조가 없습니다.

하는 self에 강한 참조를 보관 유지하는 dispatch_async를 얻으려면, 당신은 다음과 같이 뭔가를하고 싶은 것 : 블록에 strongSelf 포장

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

가 충분히 strongSelf (함으로써 self)을 유지하기 위해 dispatch_async의 원인이됩니다 전화는 postGCDBlock입니다.

+0

그게 문제를 해결했습니다. 필자는 strongSelf.postGCDBlock'을 매개 변수로 사용하여 strongSelf를 유지할 것이라고 생각했습니다. – BlackM