2009-05-07 2 views
2

저는 최근에 Apple SDK (iPhone 등)를 배우며 이해할 수없는 것을 발견했습니다. "Using NSURLConnection"에 대한 문서에서NSURLConnection의 Apple SDK 설명서에있는 실수 또는 혼란?

이상한 설명과 예제 코드를 발견했습니다. 먼저, 다음과 같이 말합니다 :

initWithRequest : delegate : 메시지를 받자 마자 즉시 다운로드가 시작됩니다. 델리게이트가 connectionDidFinishLoading : 또는 connection : didFailWithError : 메시지를 수신하기 전에 언제든지 취소 할 수 있습니다.

 
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

    if (theConnection) { 

    // Create the NSMutableData that will hold 

    // the received data 

    // receivedData is declared as a method instance elsewhere 

    receivedData=[[NSMutableData data] retain]; 

    } else { 

    // inform the user that the download could not be made 

    } 

그래서, 다운로드가 즉시 theConnection가 초기화 될 때 다른 스레드에서 즉시 시작해야한다는 것을 나에게 보인다

다음, 그것은 다음의 코드 조각을 보여줍니다. 이것은 코드가 비 블로킹 (nonblocking)하고 위임자 (이 경우에는 self)에게 메시지를 다시 보내기 때문에 명확합니다. 그러나 receivedData의 (자동 출시 스타일) 할당은 다른 스레드가 시작된 이후에 이 발생합니다. 이것은 안전하지 않은 경쟁 조건이 아닌가? 매우 빠른 서버 응답 (예 : 루프백 장치 이상) 또는 재수없는 스레드 예약의 경우 충돌, 메모리 누출 또는 데이터 손실이 발생할 수 있습니까? theConnection이 초기화되기 전에 receivedData를 할당하는 것이 더 바람직하지 않겠습니까? 그렇다면 위의 else case에서 방금 릴리스하십시오.

나는이 코드 조각으로 혼란 스럽다. 누군가 나를 위해 그것을 밝힐 수 있기를 바란다. 어떤 정보를 감사합니다,

루디 Cilibrasi

답변

6

에는 경쟁 조건이 없습니다. 다운로드는 별도의 스레드에서 백그라운드에서 시작되지만 다운로드 진행률을 알리기 위해 대리인에게 보낸 메시지는 항상 다운로드를 시작한 스레드에서 호출됩니다.

연결이 생성되기 전에 확실하게 NSData를 할당 할 수 있습니다. 연결에 : didReceiveData : 메서드를 할당 할 수도 있습니다. 저장하려는 데이터가 없으면 NSData가 할당되지 않도록해야합니다.

나는이 예제가 가능한 한 짧게 작성되었으므로, 무의미한 코드를 많이 사용하여 프리젠 테이션을 혼동하지 않을 것이라고 생각한다. the documentation for NSURLConnection에서

:

NSURLConnection’s delegate methods allow an object to receive informational callbacks about the asynchronous load of a URL request. Other delegate methods provide facilities that allow the delegate to customize the process of performing an asynchronous URL load.

Note that these delegate methods will be called on the thread that started the asynchronous load operation for the associated NSURLConnection object.

+0

그건 의미가 있습니다. 제 연구를 위해 모든 위임 메시지가 주 스레드를 통해 전송된다는 주장을 뒷받침하는 URL을 제공 할 수 있습니까? 도움과 정보를 보내 주셔서 감사합니다. –

+1

NSURLConnection의 위임 메시지는 실행 루프를 통해 마샬링되므로 제어권이 반환 된 후에 만 ​​발생할 수 있습니다. – rpetrich

+0

Mark Bessey와 rpetrich에게 도움을 주신 것에 대해 대단히 감사드립니다. 이것은 지금 나에게 분명히 드러났으며 나는 그것을 고맙게 생각합니다. –

2

여기에는 경쟁 조건이 없습니다. NSURLConnectionNSRunLoop을 사용하여 이벤트를 전달합니다. 따라서 다음 이벤트 루프가 시작될 때까지 어떠한 데이터도 사용자에게 도달 할 수 없습니다.

즉, 데이터가 실제로 되돌아 오더라도 다음 이벤트 루프 때까지 connection:didReceiveData:에 대한 호출이 발생하지 않으며로드를 시작한 스레드에서 connection:didReceiveData:이 호출됩니다. 따라서 나머지 모든 실행 루프를 순서대로 수행해야합니다. "즉시"란 "시작하려면 아무 것도 할 필요가 없다"는 의미입니다.

이것은 추측이나 변경 가능한 구현 세부 사항이 아닙니다. 이는 코코아의 디자인 원칙에 기반합니다. Cocoa를 가장 잘 이해하려면 주 스레드에서 거의 모든 것이 발생한다고 가정합니다. 프레임 워크는 종종 구현 세부 사항으로 스레드를 생성 할 수 있지만 항상 그렇지 않은 환상을 제공합니다.따라서 본질적으로 비동기 작업은 이후 이벤트 루프에 표시됩니다. 보충적이지는 않지만 멀티 태스킹이 코코아 방식입니다.

+0

그게 내 브라우저 창을 열어 두어 실제로 뭔가에 응답하기 전에 가르쳐 주겠다 .... 예, 나는 정답을 가지고있는 Mark를 완전히 반복했습니다. –

+0

Upvoted, NSRunLoop에 대한 추가 세부 정보를 추가 했으므로 내가 아직 얻지 못했던 부분입니다. –

+0

고맙습니다. 나는 원래이 글에 다른 것을 찾아 보았지만, 흥미로운 몇 가지 흥미로운 질문을 던졌고 그 대답은 잘 쓰여지고 유익하고 즐거운 읽기였다. 나는 마지막 줄을 가장 좋아한다. 한 스레드가 다른 스레드에서 사건을 일으키지 않고 사건을 일으킬 수있는 방법에 대한 내 자신의 갑작스런 생각을 말했습니다 (나는 선동적이라고 생각했지만 협조적이었습니다 ...). – RonLugge

관련 문제