0

최근 블록에서 자기를 참조해야 할 때이 트릭을 배웠습니다.ARC로 더블 블록에서 셀프 캡핑하기

__weak MyObject *safeSelf = self; 
[self doWithCompletionBlock:^{ 

    HMFInventoryBatchItemsController *strongSelf = safeSelf; 
    if (strongSelf) { 
     [strongSelf doSomethingElse]; 
    } 
}]; 

하지만 블록 내에 블록이 있으면 어떻게 될까요? 같은 일을 다시해야합니까?

__weak MyObject *safeSelf = self; 
    [self doWithCompletionBlock:^{ 

     HMFInventoryBatchItemsController *strongSelf = safeSelf; 
     if (strongSelf) { 

      __weak MyObject *saferSelf = strongSelf; 
      [strongSelf doAnotherThingWithCompletionBlock:^{ 

       HMFInventoryBatchItemsController *strongerSelf = saferSelf; 
       if (strongerSelf) { 
        [strongerSelf doSomethingElse]; 
       } 
      }]; 
     } 
    }]; 

또는이 잘

__weak MyObject *safeSelf = self; 
    [self doWithCompletionBlock:^{ 

     HMFInventoryBatchItemsController *strongSelf = safeSelf; 
     if (strongSelf) { 

      [strongSelf doAnotherThingWithCompletionBlock:^{ 

        [strongSelf doSomethingElse]; 

      }]; 
     } 
    }]; 
+1

왜 HMFInventoryBatchItemsController로 자기 재 할당 * strongSelf = safeSelf; 자기는 블록의 소유권 이니까? –

+0

당신은 ivar에 액세스하고 싶지 않으면 블록에서 강력한 참조를 만들 필요가 없습니다. – Elden

+0

이 기사를 참조로 찾았습니다. http://amattn.com/2011/12/07/arc_best_practices.html – Hackmodford

답변

2

좋은 대답은 다릅니다.

__weak MyObject *safeSelf = self; 

[self doWithCompletionBlock:^{ 
     [safeSelf doAnotherThingWithCompletionBlock:^{ 
       [safeSelf doSomethingElse]; 
     }]; 
}]; 

그 이유는,이다 생각 그 방법은 그것이 선택은 일반적으로 가정 self에 대한 참조를 보유하고 있으며 경우 -doAnotherThingWithCompletionBlock를 호출 할 때 자기를 역 참조하는 것이 : 그것은 할 일반적으로 안전하지 않은 ivars에 액세스하려면 충돌이 발생합니다. 실제로 참조를 보유하지 않기 때문입니다.

그래서 새로운 약한 참조를 취할 필요가 있는지 여부는 필요하거나 원하는 평생의 의미에 달려 있습니다.

편집 : 그런데

, 그 소리조차 당신이 CLANG_WARN_OBJC_RECEIVER_WEAK 설정으로 엑스 코드에서 사용할 수 있습니다 그 문제에 대한 경고가 (CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK를 우리가 그것에있어 유용합니다)

+0

아마도 "선택자"대신 "방법"을 의미 할 것입니다. 그리고 아마도 "ivars를 dereferencing하는 것"대신에 "ivars를 참조하는 것"을 의미합니다.'self-> someIvar '를 의미합니다.) – CouchDeveloper

+0

실제로 대답을 다시 말하면서 – JTAS

+0

좋아, 좋아 보인다. ;) – CouchDeveloper

0
__block MyObject *safeSelf = self; 

    [self doWithCompletionBlock:^{ 
      [safeSelf doAnotherThingWithCompletionBlock:^{ 
        [safeSelf doSomethingElse]; 
      }]; 
    }]; 

이다는 그것이 않습니다 일반적으로해야 무엇을 할 것인가 바랍니다. 컴파일러에게 블록 범위에 관계없이 __weak MyObject *를 유지하지 말라고 명령하십시오. 사실은 내가 테스트하지 않았다. 그 동안 실제로 MyObject *를 보유 할 경우 나는 놀라게 될 것입니다.

+0

테스트 방법이 있습니까? – Hackmodford

+0

retaincount를 사용하여 safeself가 블록 안에 +1 카운트를 가지고 있는지 살펴볼 수 있습니다 (물론 "셀프"가 다른 곳에 유지되지 않는다는 것을 보장 할 수있는 간단한 코드를 작성하십시오). 두 번째 방법은 블록 호출을 사용하여 객체를 해제 할 때입니다 (블록이 ivars이고 함수 범위에 국한되지 않는다고 가정). dealloc이 호출되지 않으면 블록에 블록 소유권 객체가 유지됩니다. "__weak"의 목적은 실제로 그것을 막는 것입니다. –