6

블록에 대한 업데이트를 보려면 스카치 변수에 __block 저장 유형이 필요하지만 객체에 언제 필요합니까? 실제로 __block 일반 개체에 대한 저장소 형식을 사용해야 할 때 보일지 모르겠지만 __weak 블록 내에서 사용되는 자체 참조를 캡처 할 때 사용해야합니다.ARC가있는 객체 참조에서 __block 키워드를 사용하는 경우

+0

[무엇 __weak과 __block의 차이 참조?] (http://stackoverflow.com/questions/11773342/what-the-difference-between-weak-and-block-reference) –

+0

내가 특별히 요구하는 것은 : '__block' 저장소 유형 sh ARC를 사용할 때 non-scalar, non-self 객체 참조에 사용할 수 있습니까? 그 다른 링크가 그 질문에 답하면 나는 그것을 놓쳤다. – chinabuffet

+0

@chinabuffet : 스칼라 유형과 객체 포인터 유형에 대한 작동 방식에는 차이가 없습니다. – newacct

답변

15

__block은 블록 내부의 코드로 값을 변경하려는 경우 스칼라 변수에 필요합니다. 캡처 된 스칼라는 블록 안에 const으로 나타나므로 변경할 수 없습니다. 객체에 대한 포인터가있는 경우에도 동일한 구별이 적용됩니다. 즉, 캡처 된 포인터 자체는 const 포인터가되어 수정할 수 없지만 가리키는 객체는 블록 내부의 코드로 수정할 수 있습니다. 포인터가 가리키는 객체를 변경하려면 포인터 자체가 변경되어야하므로 포인터는 __block 유형으로 선언해야합니다. 객체 자체를 __block으로 선언 할 필요는 없지만 객체를 가리키는 포인터 만 변경할 수 있어야합니다.

올바른 정신 모델을 갖고 있다면 블록을 혼동하지 않습니다. 블록은 스택에 처음 할당되므로 스택 프레임이 팝되면 어휘 범위가 파괴 될 때 사라집니다. 블록이 작성된 어휘 범위의 수명이 지나면 블록이 중단되도록하려면 Block_copy()을 사용하여 힙으로 이동하거나 -copy 메시지를 보냅니다. 블록을 힙에 복사하면 캡처 된 const 변수가 모두 따라 가고 변수 const이 가리키는 모든 객체가 유지됩니다. 블록이 힙에서 제거되면 const 변수가 가리키는 모든 객체가 해제됩니다.

__block "under the hood"변수는 블록에 포함 된 컴파일러에서 사용되는 간접 참조의 추가 레이어를 가지므로 블록이 힙에 복사되면 캡처 된 __block 변수도 마찬가지입니다. 보이지 않는 포인터는이 __block 변수의 새 힙 위치를 가리 키도록 조정됩니다. 즉, __block 변수의 주소가 변경 될 수 있으므로 해당 주소를 사용하는 경우주의해야합니다. __block 변수가 어떤 의미에서 블록 외부에 존재하므로 이러한 변수를 블록 외부의 코드에서 읽고 수정할 수 있음을 알 수 있습니다.

나는 간단한 봤는데,하지만 당신은 복잡성 증가에 나와, 여기에 더 나은 설명을 찾을 수 있습니다 또한

http://ios-blog.co.uk/tutorials/programming-with-blocks-an-overview/

http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html

http://www.mikeash.com/pyblog/friday-qa-2011-06-03-objective-c-blocks-vs-c0x-lambdas-fight.html

+0

블록이 어딘가에 참조로 전달되면, 그 블록을 매개 변수로받는 것은 무엇이든 나중에 사용할 블록을 즉시 복사해야합니까? – chinabuffet

+0

블록 참조가 블록이 정의 된 어휘 범위 (스택 프레임)보다 오래 지속될 수 있으면 블록 객체를 힙으로 이동하려면 복사해야합니다. 나는 블록을 만들 때 사본을 만드는 것이 창조물로부터 떨어진 장소에서 이러한 사본을 만드는 것보다 안전하다고 생각할 것입니다. – Fred

0

함수 레벨 변수로 사용됩니다. 이들은 블록 (및 엔 클로징 범위) 내에서 변경 가능하며 참조하는 블록이 힙에 복사되면 보존됩니다. __block 기억 수식어로 선언 된 둘러싼 어휘 범위의 로컬 변수는 참조로 제공되므로 변경할 수 있습니다. 변경 사항은 동일한 어휘 범위 내에 정의 된 다른 블록을 포함하여 둘러싸는 어휘 범위에 반영됩니다.

__block 변수는 변수의 어휘 범위와 변수의 어휘 범위 내에서 선언 또는 작성된 모든 블록 및 블록 사본간에 공유되는 저장소에 있습니다. 따라서 프레임 내에서 선언 된 블록의 사본이 프레임의 끝 부분을 넘어 서면 (예 : 나중에 실행하기 위해 대기열에 보관 됨) 저장 장치가 스택 프레임을 파괴하지 않고도 보존됩니다. 따라서 블록 내에서 객체를 수정해야하거나 스택 프레임을 파괴 한 후에 객체가 필요할 때 사용할 수 있습니다.

관련 문제