문제

물체를 할당하고 시작하는 다음 두 가지 방법의 차이점은 무엇입니까?

AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];

그리고

self.aController= [[AController alloc] init];

대부분의 Apple 예제는 첫 번째 방법을 사용합니다. 왜 할당, 이니 및 객체를 한 다음 즉시 릴리스합니까?

도움이 되었습니까?

해결책

모든 객체에는 참조 수가 있습니다. 0으로 이동하면 객체가 처리됩니다.

재산이 선언되었다고 가정합니다 @property (retain):

첫 번째 예, 한 줄씩 :

  1. 객체는 생성됩니다 alloc, 참조 수는 1입니다.
  2. 객체가 넘겨집니다 self'에스 setAController: 그것을 보내는 방법 retain 메시지 (메소드가 객체가 어디에서 오는지 알지 못하기 때문에)는 참조 수를 2로 증가시킵니다.
  3. 호출 코드에는 더 이상 객체 자체가 필요하지 않으므로 호출합니다. 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를 사용하는 경우 정적 분석기로 이러한 코드를 감지하는 데 도움이 될 수 있습니다. 빌드 >> 빌드 및 분석을 누르십시오

alt text

이것은 그러한 코드에서 매우 유용한 메시지를 보여줍니다.

alt text

또 다른 점은 예제가 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가 보유하기 때문이 아닙니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top