객체를 할당하고 객관적으로 할당 c
-
03-07-2019 - |
문제
물체를 할당하고 시작하는 다음 두 가지 방법의 차이점은 무엇입니까?
AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];
그리고
self.aController= [[AController alloc] init];
대부분의 Apple 예제는 첫 번째 방법을 사용합니다. 왜 할당, 이니 및 객체를 한 다음 즉시 릴리스합니까?
해결책
모든 객체에는 참조 수가 있습니다. 0으로 이동하면 객체가 처리됩니다.
재산이 선언되었다고 가정합니다 @property (retain)
:
첫 번째 예, 한 줄씩 :
- 객체는 생성됩니다
alloc
, 참조 수는 1입니다. - 객체가 넘겨집니다
self
'에스setAController:
그것을 보내는 방법retain
메시지 (메소드가 객체가 어디에서 오는지 알지 못하기 때문에)는 참조 수를 2로 증가시킵니다. - 호출 코드에는 더 이상 객체 자체가 필요하지 않으므로 호출합니다.
release
, 참조 수를 감소시키는 1.
두 번째 예제는 기본적으로 1 단계와 2 단계를 수행하지만 3은 3 단계를 수행하므로 결국 객체의 참조 수는 2입니다.
규칙은 객체를 만들면 객체를 완료 할 때 객체를 공개 할 책임이 있다는 것입니다. 예에서 코드는 속성을 설정 한 후 Tempacontroller로 수행됩니다. 전화하는 것은 세터 방법의 책임입니다 retain
그 개체가 필요한 경우.
그것을 기억하는 것이 중요합니다 self.property = foo;
Objective-C는 실제로 속기입니다 [self setProperty:foo];
그리고 그게 setProperty:
방법은 필요에 따라 개체를 유지하거나 복사 할 것입니다.
재산이 선언 된 경우 @property (copy)
, 그러면 객체가 유지되지 않고 복사되었을 것입니다. 첫 번째 예에서는 원래 객체가 즉시 해제됩니다. 두 번째 예제에서, 원래 객체의 참조 수는 0이어야하더라도 1이 될 것입니다. 따라서 여전히 같은 방식으로 코드를 작성하고 싶을 것입니다.
재산이 선언 된 경우 @property (assign)
, 그 다음에 self
대상의 소유권을 주장하는 것이 아니며 다른 사람은 그것을 유지해야합니다. 이 경우 첫 번째 예제가 잘못되었습니다. 이러한 종류의 속성은 드물며 일반적으로 객체 대의원에게만 사용됩니다.
다른 팁
다른 사람들이 지적했듯이, 당신이 보여주는 두 코드 스 니펫은 동등하지 않습니다 (메모리 관리상의 이유로). 전자가 후자보다 선택된 이유에 관해서 :
후자의 올바른 공식은 될 것이다
self.aController= [[[AController alloc] init] autorelease];
전자와 비교할 때, 이것은 자동 제국 풀을 사용하여 추가 오버 헤드를 추가하며, 어떤 상황에서는 객체의 수명이 불필요하게 확장 될 때까지 (Autorelease 풀이 해제 될 때까지) 응용 프로그램의 메모리 발자국이 증가합니다.
다른 "가능한"구현 (예제의 위치에 따라)은 간단합니다.
aController = [[AController alloc] init];
그러나 인스턴스 변수를 직접 설정하면 Init 또는 Dealloc 메소드가 아닌 다른 곳에서는 강력하게 권장되지 않습니다. 다른 곳에서는 항상 액세서 방법을 사용해야합니다.
이렇게하면 샘플 코드에 표시된 구현으로 제공됩니다.
AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];
이것은 다음과 같은 모범 사례를 따릅니다.
- 자동 제출을 피합니다.
- 메모리 관리 시맨틱을 즉시 명확하게 만듭니다.
- 액세서 메소드를 사용하여 인스턴스 변수를 설정합니다.
또한 코드를 한 줄로 줄이려는 욕구는 많은 사람들이 AutorELEASS를 사용하는 이유입니다.
self.aController = [[[AController alloc] init] autorelease];
이론적으로 iPhone AutoreLease는 어떻게 든 더 비쌉니다 (왜 명확한 설명을 들어 본 적이 없음) 다른 곳에 객체를 할당 한 직후에 명시 적으로 출시 될 수 있습니다.
Xcode를 사용하는 경우 정적 분석기로 이러한 코드를 감지하는 데 도움이 될 수 있습니다. 빌드 >> 빌드 및 분석을 누르십시오
이것은 그러한 코드에서 매우 유용한 메시지를 보여줍니다.
또 다른 점은 예제가 AconTroller의 @Property 정의에 달려 있다는 것입니다.
정의 된 경우 @property (readwrite, retain) id aController;
그런 다음 예제가 작동하는 동안 작동하는 동안 작동합니다. @property (readwrite, assign) id aController;
그런 다음 추가 호출을 릴리스하면 객체를 처리하게됩니다.
당신은 또한 할 수 있습니다
@property (nonatomic, retain)AController *aController;
...
self.aController= [[AController alloc] init];
[aController release];
고정 속성을 사용하면 동일한 방식으로 작동하지만 혼란 스럽기 때문에 다른 방법 (고정 속성을 위해)을 사용하는 것이 좋습니다. 코드는 AconTroller를 할당 한 것처럼 보이고 실제로 메모리에서 삭제됩니다. SetAcontroller가 보유하기 때문이 아닙니다.