2014-04-05 2 views
7

나는 임의의 EXC_BAD_ACCESS KERN_INVALID_ADDRESS을 가졌지 만 소스를 지적 할 수는 없습니다. 그러나, 나는 궁금하네요이가있을 경우 :dealloc에서 dispatch_async를 사용해도 안전합니까?

내가 audio_queue 이렇게 만든이 :

dispatch_async(_audio_queue, ^{ 
    _audioPlayer = [[AudioPlayer alloc] init]; 
}); 

: 내가 만들고 객체가 _audioPlayer라는 액세스하는 데 사용하는

_audio_queue = dispatch_queue_create("AudioQueue", nil); 

오디오 플레이어의 소유주는 MovieView입니다.

@implementation MovieView 
{ 
    AudioPlayer *_audioPlayer 
} 

그런 다음 MovieViewdealloc 방법, 내가 가진 :

- (void)dealloc 
{ 
    dispatch_async(_audio_queue, ^{ 
     [_audioPlayer destroy]; 
    }); 
} 

이 만족할 만합니까? 블럭이 호출 될 때까지 MovieView은 이미 할당 해제되었을 것이며, _audioPlayer에 액세스하려고하면 더 이상 존재하지 않는다고 생각합니다. 이 경우인가요?

내 충돌 보고서는 말한다 :

MovieView.m line 0 
__destroy_helper_block_ 
+0

그 자리에 중단 점을 넣어 '_audioPlayer'가 아직 있는지 확인 했습니까? – Dima

+0

충돌을 지속적으로 복제 할 수 없습니다. 현재 거기에 중단 점을 넣으면 '_audioPlayer'가 여전히 존재합니다. – Snowman

+0

잘못된 액세스가 발생한 줄 번호가 있습니까? – Dima

답변

11

버그가에 테스트하지 않았습니다

- (void)dealloc 
{ 
    dispatch_sync(_audio_queue, ^{ 
     [_audioPlayer stopPlaying]; 
    }); 
} 

을 dispatch_sync 사용할 수 있습니다 ivar 액세스. 위의 -dealloc

- (void)dealloc 
{ 
    dispatch_async(self->_audio_queue, ^{ 
    [self->_audioPlayer stopPlaying]; 
    }); 
} 

당신이 dealloced 후 self을 사용하게하기 때문 깰 수에 해당 :이 인스턴스 변수가 ObjC에서 작동하는 방식 때문이다.

수정은

- (void)dealloc 
{ 
    AVAudioPlayer * audioPlayer = _audioPlayer; 
    dispatch_async(audio_queue, ^{ 
    [audioPlayer stopPlaying]; 
    }); 
} 

같은 (그것은 자주 스레드로부터 안전하지 않습니다에 명시 적 또는 암시 적으로 (. 슬프게도, 나는 생각하지 않는다 블록 참조 self) 인스턴스 변수를 통해 대한 경고가됩니다)

+0

제안 된 수정 프로그램의 로컬 변수가'__weak'가 아닌 이유는 무엇입니까? – Snowman

+3

블록이 실행되기 전에 할당이 취소 될 수 있기 때문에 약한 것이 아니며,'audioPlayer' 객체는 결코'stopPlaying' 메시지를받지 않을 것입니다. –

+0

@moby 왜 약 해져야합니까? 이것은 할당 해제 될 것이 아니라 thread-unsafe-release 오브젝트 (아마)입니다. –

-2

이 원인 인 경우, 당신은 내가이

+0

왜 downvote? –

+0

이것은 여전히 ​​암묵적으로 블록을 전달하고 따라서 'self'에 대한 참조를 다른 스레드로 전달합니다. 이것이 안전하다는 보장은 없습니다. 'if (weakAudioPlayer! = nil)'에 대한 검사 또한 중복되어 필요하다면 안전하지 않을 것입니다. –

+0

블록에서 캡처 한 유일한 변수는 약한 변수라고 생각합니다. –

관련 문제