2013-10-15 2 views
1

현재 AudioQueue 서비스를 사용하고 있으며 약간의 문제가 있습니다.C 콜백의 ARC 약한 참조

AudioQueue는 기본적으로 "사용자 데이터"를 전달할 수있는 일련의 콜백을 가지고 있습니다. 내 포인터 중 하나를이 포인터로 전달할 수 있었으면 좋겠습니다.

그래서 무슨 일하는 것은, 특정 경우에, AudioQueue이 가까운 방법으로 내 콜백을 호출하는 것입니다 :

static void HandleOutputBuffer (
    void    *aqData, 
    AudioQueueRef  inAQ, 
    AudioQueueBufferRef inBuffer 
) { 
    MyPlayerData *mpd = (MyPlayerData *)aqData; 
    ... 
} 

이 일반적으로 잘 작동하지만, 내 플레이어가 미디어의 끝에 도달하면, 그것은 할당 해제됩니다. 그러나 종종 MyPlayerData 개체가 할당 해제 된 후 콜백 HandleOutputBuffer이 호출되어 멋진 segfault가 발생합니다.

약한 참조를 사용하고 싶습니다. ARC void * 포인터를 가질 수있는 방법이 있습니까? 객체가 할당 해제 될 때마다 무언가로 설정 될 것입니다.

나는 현재 __weak 찾고 있어요,하지만 난이 사용할 수있는 권리 도구입니다 확실하지 않다 ...

+0

은'MyPlayerData'하지 객관적인 C 객체인가? 왜 그것은 무효가되어야합니까? 'id'를 사용해도 괜찮겠습니까? 'HandleOutputBuffer'를 호출 한 코드를 표시 할 수 있습니까? (문제는 호출 할 때 aqData가 이미 할당 해제되었습니다.) – micantox

+0

이 HandleOutputBuffer를 호출 할 책임이 없습니다. 오디오 버퍼를 자유롭게 사용할 수있을 때마다 (즉, 재생 된 경우) AudioQueue. 그러므로 나는 이것에 대한 통제권을 가지지 않으며, 또한 그 방법의 서명을 변경할 수도 없다. – aspyct

+1

아 맞습니다. 그러면 ARC가 관리 할 수있는 방법이 없습니다. 상황이 발생하지 않도록하는 메커니즘을 찾아야합니다. – micantox

답변

5

ARC는 객체에 대한 void * 참조를 관리하고 객체 인 경우 NULL로 설정할 수 없습니다 할당이 취소되었습니다. 객체 포인터에서 컨텍스트 포인터를 만들 때

당신은 두 가지 옵션이 있습니다

  • const void *context = (__bridge void *)mpd;

    이것은 당신이 지금 할 것입니다. 이 경우 은 오디오 큐가 콜백에서이 객체를 사용하는 한 객체가 인지 확인해야합니다. 개체가 "활성 상태로 유지"되도록

  • const void *context = (__bridge_retained void *)mpd;

    이 증가는 가이 해제되지 않는다, 즉, 물체의 수를 보유한다. 이 경우 더 이상 필요하지 않을 때 과 CFRelease(context)을 사용하여이 참조를 해제해야합니다.

참조 : http://clang.llvm.org/docs/AutomaticReferenceCounting.html#bridged-casts