2011-11-01 3 views
6

내가 상속하는 코드에서, 나는 다음을 본 적이있다 :IBOutlet 작업을위한 읽기 전용 속성을 갖고 있습니까?

@property (readonly) IBOutlet UIImageView * bgImage; 

같은 메모리 모델을 예상 할 때 :

@property (readonly, retain) IBOutlet UIImageView * bgImage; 

왜 첫 번째 속성 정의가 작동하는지 혼란스러워. 문제없이.

또한 dealloc에서 release은 다음과 같이 나타납니다.

-(void)dealloc 
{ 
    [_bgImage release]; 
    [super dealloc]; 
} 

누구나 설명을 해 주시면 감사하겠습니다. 나는 원래 개발자와 이야기를했고 그는 더 간결한 코드를 작성하려고 노력했다. 그래서 retain을 메모리 모델에서 제외했다. (불필요한 것처럼 보였다.)

IBOutlet이 기본적으로 ivar IBOutlet 문처럼 취급되는지는 읽기 전용이므로 (setter가 없으므로 기본 할당 메모리 모델은 아무런 차이가 없습니다).

IBOutlet이 절대로 변경되지 않으면 메모리 모델이없는 readonly 속성을 사용하면 실제로 속성을 정의하는 데 바람직한 방법일까요?

답변

7

iOS의 nib loader가 펜촉에 개체를 만든 다음 자동 변 환합니다. 콘센트에 대한 연결을 설정하면 setValue:forKey:을 사용하며이 키는 해당 키에 대한 setter 메서드를 호출합니다. IBOutletreadonly 속성 인 경우와 같이 설정자가없는 경우 개체는 할당되기 전에 어쨌든 으로 유지됩니다. 는 (이 리소스 프로그래밍 가이드에 Managing Nib Objects in iOS의 의역이다.) 실제 사실 그래서

, 콘센트 retain 또는 assign, 가 콘센트와 객체에 의해를 소유하고 다른 쪽 끝에서 객체로 선언되어 있는지 여부 . setter 메서드에 의해 유지되거나 setter가 발견되지 않을 때 setValue:forKey:에 의해 유지됩니다. 두 번째 경우에는 다른 가능한 소유자가 없으므로 콘센트가있는 객체를 소유자로 간주 할 수 있습니다. 따라서 펜촉의 물체는 dealloc으로 출시되어야합니다.

나는이 메모리 조건이 retain을 포함하도록 속성 특성을 변경하여 명시 적으로 만들어야한다는 것에 동의합니다. * readonly이 차이를 보이지 않는지는 (그러나 아래 참조). 개념적으로 그렇습니다. 객체는 읽기 전용이므로 명시 적으로 객체를 표시할지 여부는 객체가 IBOutlet이라는 문서로 적절하게 문서화되었는지 여부에 따라 다릅니다.

업데이트 : 아래의 Paul.s의 의견을 통해 빠른 테스트를 수행하게되었습니다.alloc, retain, releaseautorelease 호출을 기록하고 펜촉에 인스턴스를 고정하고 속성을 통해 IBOutlet 응용 프로그램 대리인에게 준 UIView 하위 클래스를 만들었습니다.

참조 계산 활동을 손으로 집계하면 해당 인스턴스는 (readwrite, assign) 일 때 net 0으로 나옵니다. 속성이 권장 된 방법으로 선언되었을 때 그물 +1이었고 (readwrite, retain)이고 일 때 (readonly, assign)이었습니다. 이 모든 것은 예상대로입니다. (readwrite, assign) 일 때, 할당 설정자는 연결을 작성하는 데 사용되며 유지되지 않습니다. readonly 일 때, 연결 메커니즘은 자체적으로 유지 보수를 수행합니다.

가장 흥미롭게도, 속성이 (readwrite, assign) (즉, 할당이 해제되었을 때)으로이보기의 배경색을 변경하여 앱을 중단하려고 시도했을 때 retain에 대한 마지막 호출이 나타났습니다.

나는 이것이 무엇을 의미하는지 생각해 봅니다 : Apple의 권고를 따르십시오. 그들은 뒤에서 무슨 일이 벌어지는 지 알고 있으며 (버그가없는) 당신을 잘못 인도하지 않을 것입니다.

(또 다른 단점은 언제나 그렇듯이 절대 참조 횟수에 대한 걱정은별로 유용하지 않을 것이라는 것입니다. 카운트는 한 번에 6 개까지, retainrelease에 - 당신은 유지하고 당신이 직접 원인이 릴리스에 대해 걱정할 필요) 물론


*이 ARC에 따라 변경됩니다.. 내가 바꿔 말한 정보는 해당 장의 "레거시 패턴"섹션에 있습니다. ARC에서 최상위 레벨이 아닌 한 은 weak이어야하며,이 경우 strong이어야합니다. 이 방법을 사용하면 뷰 계층 구조 (하위 뷰를 유지하는 뷰)에 의존하여 자신을 유지 관리 할 수 ​​있습니다.

+0

'콘센트가 retain 또는 assign으로 선언되는지, 반대쪽 끝에있는 객체는 콘센트가있는 객체에 의해 소유됩니다. (이것은 너무 명확하지 않습니다.) 이것은'readonly'로 설정된 경우에만 해당합니까? 만약'(assign, readwrite) '이라면 확실하게 non-retainer가 사용되며'retain'은 사용되지 않을 것입니다. - 나는 그것이 단지 약간 모호한 당신의 대답의 유일한 부분이라고 언급한다. –

+0

나는 그렇게 생각한다. 그것은 분명히 말하는 것 같다. –

+2

@ Paul.s : 내 업데이트 참조 - 나는 참고 활동을 손으로 계산하기로 결심했으며 그 결과는 유익했다. –

2

속성 대신 IBOutlet 인스턴스 변수를 만들면 Xcode가 dealloc에 ​​자동으로 릴리스를 생성한다는 Apple에 버그가보고되었습니다. iOS 용 Xcode는 올바른지 여부에 관계없이 항상 IBOutlet 용 릴리스를 생성합니다.

인사 IBOutlet은 읽기/쓰기로 문서화된다는 것을 의미하기 때문에 IBOutlet 속성을 좋아하지 않지만 대부분 (거의 항상) IBOutlet은 개념적으로 읽기 전용이어야합니다. 분명히 그들은 처음에 설정하기 위해 readwrite가되어야합니다.

+0

공용 인터페이스에서'@property (nonatomic, readonly)'와 클래스 확장에서'@property (nonatomic) IBOutlet'을 선언 할 수 있습니다. –

관련 문제