IT박스

모든 ivar는 재산이어야합니까?

itboxs 2020. 12. 29. 06:49
반응형

모든 ivar는 재산이어야합니까?


iOS 용으로 코딩 할 때 속성이 인스턴스 변수에 액세스하는 데 사용되어야한다는 점이 무엇보다도 메모리 관리에 유리한 이점이 있기 때문에 모든 곳에서 권장된다는 것을 알았습니다.

이 조언은 나에게별로 잘 어울리지 않습니다. 평범한 오래된 ivar 대신 속성을 사용하면 너무 많은 코드가 필요하며 메모리 관리에 익숙하다면 실제로 이점을 보지 못합니다. 정말 그렇게 중요합니까? 인스턴스 변수를 관리하는 방법은 무엇입니까?


모든 ivar에 대해 속성을 선언 할 필요는 없습니다. 몇 가지 사항이 떠 오릅니다.

  • ivar가 객체의 수명 동안 한 번만 할당되는 경우 속성을 선언해도 실제로는 아무것도 얻지 못합니다. 기간 동안 유지 / 복사 / 할당 init한 다음 필요에 따라 해제하면됩니다 dealloc.
  • ivar가 자주 변경되는 경우 속성을 선언하고 항상 접근자를 사용하면 메모리 관리 오류를 더 쉽게 피할 수 있습니다.
  • 속성 및 ivars가 개인용 인 경우 .h 파일이 아닌 .m 파일의 클래스 확장에 속성을 선언 할 수 있습니다.
  • iOS 4.0 이상을 대상으로 할 때 속성을 정의하고 접근자를 합성하면 헤더에서 ivar를 전혀 선언 할 필요가 없습니다.

그래서 나는 일반적으로 속성을 사용하지만 NSMutableArray객체가 할당 init하고 많은 것을 유지하는 데 사용 하는 것과 같은 경우 ivar를 다시 할당하지 않을 것이기 때문에 평범한 오래된 ivar를 사용합니다.


Daniel의 대답은 정확하지만 중요한 점을 놓친 것 같습니다. 즉:

평범한 오래된 ivar 대신 속성을 사용하면 너무 많은 코드가 필요하며 메모리 관리에 익숙하다면 실제로 이점을 보지 못합니다.

이점은 일관성입니다. 일관된 메모리 관리 및 일관된 동작.

특히,이 두 줄의 코드는 실제로 런타임에 매우 다른 동작을 가질 수 있습니다 .

iVar = [foo retain];
self.iVar = foo;

첫 번째는 인스턴스 변수의 직접 설정이며 변경 알림이 없습니다. 둘째, 따라서, 임의의 서브 세트에 따라 사용자 정의 보존 세터 거치고 프로퍼티 중 관찰자 변경 통지를 보장해 .

코드 전체에서 직접 ivar를 사용하는 경우 (클래스 내부적으로- 해당 인스턴스 외부 에서 직접 인스턴스의 ivar를 사용하는 경우 ... 코드베이스에서 작업하는 모든 계약자가 속도를 두 배로 늘려야합니다.) 변경 알림 전파를 수동으로 (일반적으로 willChangeValueForKey:/ 를 호출 하여 didChangeValueForKey) 처리 하거나 애플리케이션을 명시 적으로 엔지니어링하여 키-값 관찰에 의존하는 메커니즘을 사용하지 않도록합니다.

"너무 많은 코드가 필요합니다"라고 말합니다. 나는 그것을 보지 않는다; 위의 두 줄 코드에서 도트 구문은 더 적은 문자입니다. 전통적인 구문을 사용하여 setter 메서드를 호출하는 경우에도 코드가 적습니다.

그리고 중앙 집중식 메모리 관리의 가치를 무시하지 마십시오. 무수한 전화 사이트와 충돌 도시에서 우연히 누락 된 하나.


속성은 동일한 메서드를 반복해서 작성하지 않는 구문 설탕 일뿐입니다. 속성을 사용하면 이전 개체를 해제하고 새 개체를 무료로 유지하는 setter가 있습니다.


개인 필드의 경우-기본 유형 (BOOL / int / float 등)에만 직접 ivar를 사용하는 것이 안전하다고 제안합니다. 속성에서 메모리 관리와 관련된 모든 것을 래핑하는 좋은 방법을 찾았습니다 . 이 접근 방식의 추가 보너스는 IDE가 일반적으로 직접 ivar 액세스를 다르게 강조하므로 항상 간단한 스칼라 필드와 객체 유형 필드를 멋지게 구분한다는 것입니다.

이와는 반대로 클래스 공용 인터페이스에서 직접 ivar를 사용하지 않는 것이 좋습니다 . 언어의 동적 인 특성으로 인해 찾기, 현지화 및 수정이 매우 어려운 런타임 오류가 발생할 수 있습니다. 다음 계층을 고려하십시오.

@interface BaseControl
...
@end

@interface Label : BaseControl
...
@end

@interface Button : BaseControl {
  @public
    BOOL enabled;
}
@end

및 코드 스 니펫

- (void)enableAllButtons {
    NSArray *buttons = [self getAllButtons];   // expected to contain only Button instances
    for (Button *button in buttons) {
        button->enabled = YES;
    }
} 

이제 -getAllButtons 로직 어딘가에 오류가 있고 해당 배열에서 일부 Label이 반환되었다고 상상해보십시오. 따라서 해당 Label 클래스 인스턴스에는 할당 된 ivar가 누락됩니다. 놀라운 사실은이 경우 -enableAllButtons가 충돌하지 않는다는 것입니다. 그러나 그 시점에서 그 라벨 인스턴스 내부 구조는 손상 이는 것입니다 정의되지 않은 동작이 발생할 그들이 다른 곳에서 사용하는 경우 충돌합니다.

메모리 관리 (그리고 일반적으로-매달린 포인터 사용)와 관련된 몇 가지 인기있는 문제처럼-이런 종류의 문제는 찾아 내고 지역화하기가 어렵습니다. 오류의 모양이 일반적으로 (시간, 코드 또는 앱 흐름 측면에서) 멀리 떨어져 있기 때문입니다. 장소, 오류의 원인. 그러나 그 특정 문제로 인해 지역화 및 수정에 도움이되는 편리한 도구 (예 : 누출 / 좀비 분석기 등)도 없습니다. 문제를 재현하는 방법을 배우고 오류 상태를 쉽게 조사 할 수있는 경우에도 마찬가지입니다.

분명히 사용 @property (assign) BOOL enabled;하면 -enableAllButtons에서 런타임 예외를 쉽게 진단하고 수정할 수 있습니다.

참조 URL : https://stackoverflow.com/questions/5031230/must-every-ivar-be-a-property

반응형