2012-11-19 3 views
6

나는 매우 일반적인 상황을 일반적인 형태로 증류 할 것입니다. 일부 라이브러리 객체를 빌드하고 비동기 작업을 수행 한 다음 완료되면 위임 메서드를 다시 호출한다고 가정 해 보겠습니다. 자, 임의의 이유로 ARC 또는 콜백 블록을 사용할 수 없다고 말합니다. 구식입니다. 이 객체를 Worker라고 부르 자.대리자 콜백 기간 동안 위임자 개체 수명을 연장해야하는 방법은 무엇입니까?

이제 공용 인터페이스 외에도 Worker에 대해 알지 못하는 여러 가지 다양한 클래스가 있습니다. 그들은 노동자들을 자신의 목적으로 사용합니다. 이 클래스를 소비자라고합시다.

// "Private" method called internally when work is done. 
- (void)somethingFinished 
{ 
    [self.delegate workerDidFinish]; 
    [self someTask]; 
} 

을 그리고 어떤 특정 소비자는이 같은 콜백 처리 말한다 :

말 노동자는 다음과 같이 콜백을 위임하게 다른 아무것도 유지하지 않은 경우, 지금

- (void)workerDidFinish 
{ 
    // Assume "worker" is a retain property to a Worker 
    // instance that we previously created and began working, 
    // and that it's also the sender of the message. 
    self.worker = nil; 
    // Other code... 
} 

를 특정 작업자 예, 우리 문제가 생겼어. 작업자의 할당이 해제 된 다음 제어는 -somethingFinished 메서드로 돌아가서 -someTask을 재생되거나 가비지 메모리로 보내고 충돌 할 수 있습니다. 메모리 관리 규칙을 맹렬히 위반 한 사람은 없습니다.

여기 기술 솔루션을 요청하지 않습니다. 몇 가지 옵션을 알고 있습니다. 수정본에 대한 책임 부담이 누구에게 있는지 궁금합니다. 구성 요소 디자이너로서 처음에 [[self retain] autorelease]과 같은 메서드 지속 기간 동안 Worker의 수명이 연장되도록 Worker의 -somethingFinished 메서드를 구현해야합니까? 또는 구성 요소의 소비자가 인스턴스 메서드의 중간에서 개체를 날려 버릴 수도 있다는 것을 알고 있어야하며 나중에 인스턴스를 릴리스 할 때까지 기다려야합니까?

This question의 답변은 모두 콜백에서 개체를 릴리스하면 잘못된 생각임을 나타냅니다. 불행히도, Worker (이 인스턴스의 CLLocationManager)가 여기에서 의도적으로 피한 delegate에 얼마나 정확하게 전달되었는지에 대한 질문에는 많은 혼란스러운 정보가 있습니다. This question은 동일한 시나리오를 겪고 있으며 다른 솔루션을 제공합니다.

개인적으로 소비자가 어떻게 책임을 질 수 있는지 나는 개인적으로 볼 수 없습니다. 메모리 관리 규칙을 위반하지 않고 Worker의 공개 인터페이스를 정중하게 사용합니다. 더 이상 필요없는 인스턴스를 릴리스하는 것입니다. 그러나 다른 한편으로는, 그것은 중간에 할당 해제 될 수있는 어떤 객체라도 인위적으로 수명을 연장해야한다는 것을 의미합니까? 메시지 전달자가 메소드의 중간에 할당 해제 될 수있는 유일한 방법은 대리자 메소드가 아닙니다.

궁극적으로 누가 수정 프로그램을 담당합니까? 노동자? 소비자? 그것이 정식으로 결정될 수 있습니까?

답변

0

대리인이 알림을 받으면 worker 관찰을 시작하고 somethingFinushed 메서드가 종료 될 때만 해제해야합니다.

+0

위임자는 이미 위임자의 옵저버입니다. –

1

이 예제에서는 작업자에게 부담이 있다고 생각합니다. 내가 보는 문제는 Worker 객체가 Consumer에게 작업이 끝났음을 알린 후 내부적으로 뭔가를하고 있다는 것입니다. 근로자는 소비자를 위해서만 존재하므로 소비자의 목적이 충족되면 왜 근로자는 여전히 소비자에게 가치가없는 것을하고 있습니까? 'consumable'작업이 완료된 후에 완료해야하는 내부 작업이있는 경우 해당 작업은 Worker 객체의 인스턴스에 적절히 배치되지 않지만, 아마도 덜 휘발성이있는 라이브러리 클래스가 소유 한 다른 내부 객체가 수행해야합니다. 소비자의 행동에 의해 dealloc'd되지 않습니다.

+0

대리인을 호출하는 일부 개체가 이후의 내부 호출을 수행 할 수있는 이유가있을 수 있다고 생각하지 않습니다. 그것들은 정리 절차처럼 단순 할 수 있습니다. 이게 아니어야한다고 말하는거야? –

+0

그렇습니다. 스트레치는 아니지만 메모리 관리 시나리오를 통해 소비자와 실행 루프의 분위기에서 파괴되지 않는 객체에 클린업/내부 작업을 남겨 두는 것이 더 좋은 패턴 일 것이라고 제안하고 있습니다. – foggzilla