2017-03-02 1 views
0

모든 조건이 충족 될 때 A & B가 참이면 코드의 한 부분을 한 번만 실행하면됩니다. 따라서 나중에 모든 기준이 다시 충족되면 (A & B가 다시 true이지만 나는 신경 쓰지 않습니다.) 코드가 다시 실행되지 않습니다.다중 스레드 환경이 아닌 "dispatch_once"메서드를 구현하는 방법 모든 조건이 충족 될 때 한 번만 실행하십시오.

나는 dispatch_once가 여기에 적합하다고 생각하지 않습니다. 여기에 데이터 동기화 문제가 없으며 모든 기준이 다시 충족 될 수도 있습니다. 지금은 2 가지 방법을 시도합니다 :

  1. KVO 모든 기준은 일단 충족되면 코드를 실행하고 KVO를 중지합니다.
  2. 다른 속성을 추가하고 조건이 충족 될 때 업데이트하십시오. 모든 기준이 충족되면 코드를 실행 한 다음 특수 값으로 설정하면 코드가 다시 실행되지 않습니다. 예를 들어, A가 참일 때 & 2, B가 참일 때 & 4 일 때 초기 값을 1로 설정합니다. 따라서 7 일 때 코드를 실행하고 값을 0으로 설정하십시오. 나중에 나중에 다시 7이됩니다. .

그래서 더 좋은 방법이 있습니까?

---- 갱신 ----, 나는 또한 그것을 할 수있는 "전신"방법을 찾고 있어요 얼마나 많은 내가이 작업을 수행 할 수있는 방법을 알고 제외

. 지금은 & B가 모두 true 일 때 1 부 1 회 실행해야합니다. 2 부 1 회 C & D & E가 참일 때; E & F가 참일 때 한 번 파트 3. 내가 언급 한 두 가지 방법을 사용했다. 코드가 엉망으로 보이고 다른 사람들이 내가 성취하려고하는 것을 이해하기가 어렵습니다. if 사용자의 특정 구현에 완전히 것을 실행할 때 결정 방법

- (void)tryOnce{ 
    if (a && b){ 
     dispatch_once()... 
    } 
} 

:

답변

1

이 내가 잘못 아무것도 볼 번만 응용 프로그램 당 발생 할 가정. ab에 KVO를 사용하면 그들은 여러 위치에 수정 될 수있는 경우, 적절한 것, 또는 당신은 세터을 무시할 수 :

- (void)setA(id a) { 
    _a = a; 
    [self tryOnce]; 
} 
- (void)setB(id B) { 
    _b = b; 
    [self tryOnce]; 
} 

--- 영업 이익의 업데이트에 대한 편집 ---

한 일반적인 해결책은 될 것이다 두 개의 블록을 보유하고있는 클래스를 만들고 observeValueForKeypath:...을 재정의합니다. 이것은 당신이 (아마도) UIViewController의 observeValueForKeyPath에서 많은 지저분한 검사를 피할 수 있고 일반적으로 좋은 패턴 어디서나 당신이 동일한 메서드 (UITextView 대리자, 등 ...)로 많은 호출을 다루는 찾을 수 있습니다.

@implementation ObserveAndDoOnce 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ 
    if (!self.checkBlock || !self.finishedBlock){ return; } 
    if (self.checkBlock()) { // checkBlock returns a BOOL 
     self.finishedBlock(); 
     self.checkBlock = nil; 
     self.finishedBlock = nil; 
    } 
} 
@end 

ObserveAndDoOnce *a_and_b = [ObserveAndDoOnce new]; 
[self addObserver:a_and_b forKeyPath:keypath_for_a...]; 
[self addObserver:a_and_b forKeyPath:keypath_for_b...]; 
a_and_b.checkBlock = ... 
a_and_b.finishedBlock = ... 
+0

그러나 dispatch_once를 사용할 때 추가 된 값이 표시되지 않습니다. – Qiulang

+0

전적으로 달성하려는 대상에 따라 다릅니다. 'dispatch_once'에 아무런 해가 없습니다. 만약 당신이 그것을 좋아하지 않는다면 당신은'didTryOnce'와 같은 속성이나 static var을 추가 할 수 있고'if (a && b &&! didTryOnce) ...'를 할 수 있습니다. 'dispatch_once'는 애플리케이션 실행 당 최대 한 번만 실행됩니다 ** 보장 된 ** 반면'didTryOnce' 경로로 가면 여러분은 여러분의 객체를 할당 해제하거나 그렇지 않으면'didTryOnce'를 리셋 할 수 있고 그 코드 세그먼트를 실행시킬 수 있습니다 나중에 다시. – arsenius

+0

성취하려는 일에 대한 제 질문이 업데이트되었습니다. – Qiulang