ARC-__unsafe_unretained의 의미?


80

내가 제대로했는지 확인하고 싶습니다.

  1. 내가 __unsafe_unretain소유하지 않은 물건이 필요 합니까?
  2. 객체 인 경우 __unsafe_unretained사용해야합니까 필요 assign에가 @property? 이는 객체가 유지되지 않고 내가 할당 한 객체를 참조한다는 의미입니까?
  3. 델리게이트를 제외하고 언제 사용하고 싶습니까?
  4. ARC 관련인가요 아니면 이전에 사용 했나요?

답변:


192

LLVM 컴파일러 3.0을 소개합니다 네 개의 새로운 소유권 예선 : __strong, __autoreleasing, __unsafe_unretained,와 __weak. 처음 세 개는 사양에 따라 ARC 외부에서도 사용할 수 있습니다 .

Joshua가 지적했듯이 기본적으로 모든 포인터는 __strongARC 아래 에 있음을 암시합니다 . 즉, 개체가 해당 포인터에 할당 될 때 해당 포인터가 참조하는 한 유지됩니다. 이것은 대부분의 경우 괜찮지 만 여기 에 내 대답 에서 설명했듯이 유지주기의 가능성을 열어줍니다 . 예를 들어 인스턴스 변수로 다른 개체를 포함하는 개체가 있지만 두 번째 개체에 대리자 인 첫 번째 개체에 대한 강력한 링크가있는 경우 두 개체는 해제되지 않습니다.

이러한 이유로 __unsafe_unretained__weak한정자가 존재합니다. 가장 일반적인 용도는 대리자에 대한 것입니다. 여기에서 해당 대리자에 대한 속성을 weakor unsafe_unretained속성 ( assignis effective unsafe_unretained)으로 정의한 다음 각 인스턴스 변수를 __weak또는 로 표시하여 일치 __unsafe_unretained시킵니다. 즉, 델리게이트 인스턴스 변수는 여전히 첫 번째 개체를 다시 가리 키지 만 해당 개체가 유지되지 않으므로 유지주기가 중단되고 두 개체가 모두 해제 될 수 있습니다.

이는 델리게이트 외에도 코드에서 형성 될 수있는 다른 유지주기를 중단하는 데 유용합니다. 유용하게도 Leaks 계측기에는 이제 애플리케이션에서 발견 한 유지주기를 그래픽 방식으로 보여주는 Cycles보기가 포함됩니다.

모두 __unsafe_unretained__weak객체의 보유를 방지하지만, 약간 다른 방식이다. 의 경우 __weak객체에 대한 포인터가 가리키는 객체 nil의 할당 해제시 로 변환 되므로 매우 안전한 동작입니다. 이름에서 알 수 있듯이 __unsafe_unretained는 할당이 취소 된 후에도 개체가 있던 메모리를 계속 가리 킵니다. 이로 인해 할당 해제 된 개체에 액세스하여 충돌이 발생할 수 있습니다.

그렇다면 왜 사용 __unsafe_unretained하겠습니까? 안타깝게도 __weakiOS 5.0 및 Lion에서만 배포 대상으로 지원됩니다. iOS 4.0 및 Snow Leopard로 다시 타겟팅하려면 __unsafe_unretained한정자 를 사용 하거나 Mike Ash 's와 같은 것을 사용해야합니다. MAZeroingWeakRef .


2
그리고 물론 상수 등의 __unsafe_unretainedC 배열을 정의하는 데 유용 할 수 있습니다 NSString. 예NSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };
jlehr

2
@shannoga-아니요, __weak이러한 종류의 포인터를 사용하려면 한정자 로 수동으로 지정해야 합니다. __unsafe_unretained순전히 5.0 대상으로 계속 사용할 수 있으며 __weak. 타겟이 지원하는지 여부에 따라 두 모드 사이를 전환 할 무언가를 원한다면 여기에서 제안하는 것과 같은 컴파일러 별 정의를 사용할 수 있습니다. stackoverflow.com/a/8594878/19679
Brad Larson

4
@jlehr- NSString *myStrings = { @"Foo", @"Bar" };유효한 Objective-C 구문이 아닙니다. 그 자체로 @"Foo"유형 NSString*이 있습니다. 아마도 당신은을 의미했을 것입니다 NSString *myStrings[] = { @"Foo", @"Bar" };. 그러나 그 경우에는 어떻게 __unsafe_unretained특히 유용 할 것인지 정말로 이해하지 못합니다 .
Quuxplusone 2012

2
@Quuxplusone 두 계산 모두에서 오른쪽-C 배열과 구조체를 혼합했습니다. 내가 말 했어야 __unsafe_unretained하는 것은 NSString 상수를 가리키는 유용한 C 구조체 멤버가 될 수 있다는 것입니다. 예struct foo { __unsafe_unretained NSString * const s; int x; };
jlehr


4
  1. 아니요, 사용할 수도 있습니다. weak 소유하지 않은 개체 .
  2. 아니요, 사용할 수도 있습니다. unsafe_unretained 속성 .
  3. 내 이해는 unsafe_unretained항목이 weak가리키는 항목이 해제 될 때 항목을 지우는 추가 안전없이 항목과 같습니다 (및 그에 따른 오버 헤드).
  4. 이것은 전적으로 ARC 일입니다.

사실 이상하게도 unsafe_unretainediVar는 런타임에 설정 될 때 하나처럼 동작 strong합니다. 따라서 이것이 unsafe_unretained단순히 컴파일러 힌트 일 뿐이고 weak는 그렇지 않다고 믿게 됩니다. 자세한 내용은 여기 : stackoverflow.com/questions/11621028/...
리처드 J. 로스 III

4

__unsafe_unretainedARC 이전의 객체 기본 저장소와 동일합니다. ARC에서 기본값은 이제 __strong참조가 범위를 벗어날 때까지 참조 할 수 있음을 의미합니다.


1

__unsafe_unretained에 대한 또 다른 관찰 : __unsafe_unretained로 선언 된 iVars가있는 시뮬레이터가 아닌 장치의 앱에서 충돌이 발생했습니다 ! 예, ARC 마이그레이션의 코드에있는 버그 였지만 장치와 시뮬레이터의 차이를 처음 발견했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.