ARC는 디스패치 대기열을 지원합니까?


95

"Dispatch Queues를위한 메모리 관리"에 대한 Apple의 문서를 읽고 있습니다.

가비지 수집 애플리케이션을 구현하더라도 디스패치 큐 및 기타 디스패치 객체를 유지하고 해제해야합니다. Grand Central Dispatch는 메모리 회수를위한 가비지 컬렉션 모델을 지원하지 않습니다.

ARC가 가비지 수집기가 아니라는 것을 알고 있지만 dispatch_retain 및 dispatch_release 내 dispatch_queue_t가 필요하지 않은지 확인하고 싶습니다.

답변:


234

짧은 대답 : 예, ARC는 디스패치 대기열을 유지하고 해제합니다.







이제 긴 대답을 위해 ...

배포 대상이 iOS 6.0 또는 Mac OS X 10.8보다 낮은 경우

dispatch_retaindispatch_release대기열 에서 사용해야 합니다. ARC는이를 관리하지 않습니다.

배포 대상이 iOS 6.0 또는 Mac OS X 10.8 이상인 경우

ARC가 대기열을 관리합니다. ARC를 사용 dispatch_retain하거나 사용할 필요가 없으며 사용할 수 없습니다 dispatch_release.

세부

iOS 6.0 SDK 및 Mac OS X 10.8 SDK부터 모든 디스패치 객체 (를 포함 dispatch_queue_t)도 Objective-C 객체입니다. 이것은 <os/object.h>헤더 파일에 설명되어 있습니다.

 * By default, libSystem objects such as GCD and XPC objects are declared as
 * Objective-C types when building with an Objective-C compiler. This allows
 * them to participate in ARC, in RR management by the Blocks runtime and in
 * leaks checking by the static analyzer, and enables them to be added to Cocoa
 * collections.
 *
 * NOTE: this requires explicit cancellation of dispatch sources and xpc
 *       connections whose handler blocks capture the source/connection object,
 *       resp. ensuring that such captures do not form retain cycles (e.g. by
 *       declaring the source as __weak).
 *
 * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
 * compiler flags.
 *
 * This mode requires a platform with the modern Objective-C runtime, the
 * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
 * or iOS 6.0 deployment target.

이것은 당신이 당신의 큐를 저장할 수 있다는 것을 의미 NSArray하거나 NSDictionary, 또는 중 하나와 속성에 strong, weak, unsafe_unretained, assign, 또는retain 속성. 또한 블록에서 큐를 참조하면 블록이 자동으로 큐를 유지한다는 의미입니다.

따라서 배포 대상이 iOS 6.0 또는 Mac OS X 10.8 이상이고 ARC를 사용하도록 설정 한 경우 ARC는 대기열을 유지하고 해제하며 컴파일러는 사용 시도 dispatch_retain또는 dispatch_release오류로 플래그를 지정합니다 .

배포 대상이 적어도 경우 아이폰 OS 6.0 또는 Mac OS X 10.8, 그리고 당신은 ARC를 사용할 수있다 , 당신은 수동으로 유지하고, 당신의 대기열을 해제해야합니다 중 하나를 호출하여 dispatch_retain하고 dispatch_release, 또는 큐 보내 retainrelease(같은 메시지 [queue retain][queue release]).

기존 코드베이스와의 호환성을 위해, 당신은 정의하여 목표 - C 객체로 당신의 큐를 볼 수 컴파일러를 방지 할 수 있습니다 OS_OBJECT_USE_OBJC0. 예를 들어, .pch파일에 ( #import문 앞에 ) 다음을 넣을 수 있습니다 .

#define OS_OBJECT_USE_OBJC 0

또는 OS_OBJECT_USE_OBJC=0빌드 설정에서 전 처리기 매크로로 추가 할 수 있습니다 . 사용자가 설정 한 경우 OS_OBJECT_USE_OBJC0, ARC는 것 아니 유지하거나 당신을 위해 대기열을 해제, 당신은 사용하여 직접해야 할 것 dispatch_retain하고 dispatch_release.


1
그러나 새로운 변경 사항은 디스패치 객체를 Objective-C 객체로 지정합니다. 따라서 ARC가 비활성화 된 경우에도 이러한 객체는 다른 모든 Objective-C 객체와 마찬가지로 블록에 캡처되면 자동으로 유지됩니다.
Jody Hagins 2012 년

3
흥미로운 엣지 케이스가 있습니다. 라이브러리가 iOS 5.1에 배포되고 앱이 6.0에 배포되고 ARC를 사용 하는 경우 5.1 코드 의 개체 dispatch_release ARC를 사용해야 합니다. 그렇지 않으면 어떤 것 (컴파일러에 의해 생성 된 코드? 런타임 자체?)이 두 번째로 객체를 해제하려고합니다. NULLdealloc
스티븐 피셔

Mac OS 10.7을 사용할 때 생성 한 다른 소스 객체를 디스패치해야합니까?
p0lAris

OS X 10.7에서 모든 GCD 개체를 수동으로 유지 / 해제해야합니다.
rob mayoff

23

여기에서 후속 조치를 취하십시오. 최소 배포 대상이 iOS 6 인 경우 이제 ARC에서 관리합니다.


이것은 Mountain Lion에도 적용됩니다. 배포 대상이 iOS 6 또는 Mountain Lion 인 경우 ARC에서 허용되지 않는 객체에 릴리스 메시지를 보내는 매크로이므로 기본적으로 dispatch_release를 사용할 수 없습니다.
Emil Eriksson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.