2011-01-18 3 views
0

코코아의 메모리 관리 개념을 이해하려고합니다. 나는 다음과 같은 부분 :::에 붙어코코아의 메모리 관리

//This is wrong code. But i want to understand why it is wrong! 
- (void) setEngine: (Engine *) newEngine 
{ 
     [engine release]; 
     engine = [newEngine retain]; 
} 

때 newEngine 및 엔진입니다 같은, 그럼 어떻게 코코아는 인스턴스 변수로 취급 할 수있는 하나 매개 변수로 한 결정합니까? 예를 들어

:

Engine *engine = [Engine new]; // count: 1 
Car *car1 = [Car new]; 
Car *car2 = [Car new]; 

[car1 setEngine: engine]; // count: 2 -----How is the retain count 2 here? 
[engine release]; // count 1 

[car2 setEngine: [car1 engine]]; 

난 내 프로그램의 효율성을 유지하도록 철저하게이 개념을 배우고 싶은대로 도와주세요. 나는 많은 사람들이 내게로 붙어 있고 내 친구들은 .. 미리 감사드립니다 ... :)

+0

당신은 코드를 포맷 "{}"아이콘을 사용할 수 있습니다

여기에 전체 예입니다. 또한 프레임 워크 이름은 COCOA가 아니라 "Cocoa"입니다 (약어가 아닙니다). –

+0

좋아요. 명심할 것입니다. –

답변

3

첫째, 당신은 설정자가 서로 다른지 확인하기를 원합니다 :

- (void)setEngine:(Engine *)newEngine { 
    if (engine != newEngine) { 
     [engine release]; 
     [newEngine retain]; 
     engine = newEngine; 
    } 
} 

다음은이 방법 안에 일어나는 내용은 다음과 같습니다

  1. 검사는 전달 된 엔진은 우리가 이미 가지고있는 것과 다른 것을 볼 수 있습니다. 동일하면 아무 것도 할 필요가 없습니다.
  2. 오래된 엔진을 출시하십시오. 우리가 소유하고있는 마지막 객체라면 보유 수는 0이되고 할당이 해제됩니다. 이전 엔진이 nil 인 경우 release 메시지는 단순히 무시됩니다.
  3. 신품 엔진을 유지하십시오. 다른 곳에서 배포 된 경우 소유권을 확보했기 때문에 할당이 취소되지 않습니다. 새 엔진이 nil 인 경우 retain 메시지는 무시됩니다.
  4. engine 인스턴스 변수를 newEngine으로 설정하십시오. 당신이 생성 된 때 1로 시작했기 때문에 setEngine:이 호출 한 후

둘째, 수를 유지하는 이유는 두 가지입니다. 그런 다음 car1에 할당하여 보관 횟수를 2로 유지합니다. 외부 번호가 이고 car1이 소유하고 있기 때문에 보유 횟수가 2입니다. car1과 car2에 동일한 방법 ([car2 setEngine:car])으로 전달하여 보유 개수를 3으로 가져와야합니다. car1과 car2로 전달한 후에는 외부 코드를 릴리스 할 수 있습니다. 그러면 Obcjective-C에 외부 코드가 더 이상 소유하지 않으므로 소유권은 car1과 car2에만 있습니다.

// create an engine, we will own it for now 
Engine *engine = [[Engine alloc] init]; 

/* engine retain count: 1, owned by this context */ 

Car *car1 = [[Car alloc] init]; 
Car *car2 = [[Car alloc] init]; 

// pass engine along to cars 
[car1 setEngine: engine]; 
[car2 setEngine: engine]; 

/* engine retain count: 3, owned by car1, car2 and this context */ 

// release engine, we no longer need it 
[engine release]; 

/* engine retain count: 2, owned by car1 and car2 */ 
+0

Thnx Simon for the answer ... 나는 지금까지 설명 된대로 이해했습니다 ... 그러나 setEngine의 실행이 어떻게 이루어지는 지 아직 명확하지 않습니다. 동일한 예와 같이 : - (void) setEngine : (Engine *) newEngine { [엔진 릴리스]; // 첫 번째 엔진이 출시되었습니다. 인스턴스 변수 또는 메소드 외부에서 생성 된 객체? 엔진 = [newEngine 유지]; } –

+0

'setEngine :'내부에서 일어나는 일에 대한 설명을 추가했습니다. –

+0

... 그리고 방금 다시 편집하여 좀 더 명확합니다. –