ios - 레퍼런스 - swift<~




__weak 객체를 메시징 하시겠습니까? (2)

약한 물체에 메시지를 보내면 어떻게됩니까? 메시지를 보내는 것이 객체를 소유하고 반환 될 때까지 메모리에 보유합니까?

나는이 패턴을 생각하고있다.

__weak MyObject *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf doSomeAction];
});

메시지가 전송 될 때 weakSelf 가 0이 아닌 것으로 가정하면 weakSelf 이 작동하는 동안 할당이 취소되거나 doSomeAction 반환 될 때까지 유효하게 유지되는 것이 보장됩니까?


너는 물었다 :

weakSelf 가 메시지를 보낼 때 nilweakSelf 가정하면 weakSelf 이 작동하는 동안 할당이 취소되거나 doSomeAction 반환 될 때까지 유효하게 유지 될 수 있습니까?

예, doSomeAction 반환 될 때까지 유효 할뿐만 아니라 나머지 블록에서도 유지됩니다. 다음을 고려하세요:

- (void)dealloc
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)startBackgroundOperation
{
    __weak MyObject * weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [weakSelf doSomeAction];
        sleep(5);
        [weakSelf doSomeAction2];
    });

    sleep(1);
}

- (void)doSomeAction
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)doSomeAction2
{
    NSLog(@"%s", __FUNCTION__);
}

이 예제에서는 블록이 시작될 때 오브젝트가 범위에 있는지 확인하지만 doSomeActiondoSomeAction2 사이의 범위를 벗어나지 만 블록은 블록 완료를 위해 블록을 유지하는 것처럼 보입니다. 그러나 doSomeAction 의 호출을 주석 처리하면 weak 참조는 doSomeAction2 도달 할 때 doSomeAction2 예상대로입니다.

옆으로, WWDC 2011 - # 322 - Objective-C Advancements In-Depth 에서 그들은 (비디오에 약 27 분) 지적하고, weakSelf 역 참조하는 경우, 레이스 상태에서 자신을 보호하기 위해 파견 블록 내부의 참조 :

__weak MyClass *weakSelf = self;

dispatch_async(dispatch_get_main_queue(), ^{
    MyClass *strongSelf = weakSelf;
    if (strongSelf)
        [strongSelf->myView doSomeViewAction];
});

그것은 블럭이 지속되는 동안 그것을 유지할 것이다 (블럭이 실행될 때까지 이미 할당 해제되지 않았다고 가정 할 때).


Clang ARC 문서에서 :

읽기 작업은 lvalue에 대한 lvalue - rvalue 변환을 수행 할 때 발생합니다.

  • __weak 객체의 경우 현재 pointeeee가 유지 된 후 현재 전체 표현식의 끝에서 해제됩니다. 이는 과제 및 지적 자의 최종 릴리스와 관련하여 원자 적으로 실행되어야합니다.

약한 참조를 전달하면 변수에 대한 왼쪽에서 오른쪽으로의 변환이 수행되므로 약 참조의 값이 유지되고 현재 전체 표현식 (기본적으로 구문)의 끝에서 해제됩니다. 기본적으로 현재 구문에 대해서만 범위가 지속되는 강력한 변수에 할당 한 다음 그 강력한 변수에 메시지를 보내는 것과 같습니다.

여기서 테이크 어웨이는 약한 변수를 한 번만 메시지로 보내고 다시는 건드리지 않으려는 경우 약한 참조가 nil 끝나는 경우 메서드에 대한 인수를 평가하는 부작용은 신경 쓰지 않는다면 계속해서 약한 참조를 직접 전달하십시오. 그러나 약한 참조를 두 번 (별도의 명령문에서) 참조해야하거나 인수를 평가할 때의 부작용이 중요하다면, 진행하기 전에 강력한 변수에 할당하고 nil 테스트해야합니다.





automatic-ref-counting