2009-10-11 2 views
3

저는 iPhone 개발에 관한 책을 읽었으며 예제 코드에서 계속 볼 수있는 특별한 패턴이 있습니다. 속성이 설정 될 때마다 먼저 속성의 새 값에 대한 포인터를 할당 한 다음 속성을 포인터로 설정 한 다음 포인터를 놓습니다. 예 :속성 값을 설정할 때 불필요한 임시 변수가 필요합니까?

인터페이스 :

@interface DoubleComponentPickerViewController : UIViewController { 
    NSArray *breadTypes; 
} 

@property(nonatomic, retain) NSArray *breadTypes; 

@end 

클래스 방법 :

- (void)viewDidLoad { 
    NSArray *breadArray = [[NSArray alloc] initWithObjects:@"White", @"Whole Wheat", @"Rye", @"Sourdough", @"Seven Grain", nil]; 
    self.breadTypes = breadArray; 
    [breadArray release]; 
} 

이 작업을 수행하는 대신 바로 다음을 수행 할 이유가 있습니까? 의심의 여지가 흘리지 될 빛

- (void)viewDidLoad { 
    self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @"Whole Wheat", @"Rye", @"Sourdough", @"Seven Grain", nil]; 
} 

감사합니다 :)

+0

어떤 책을 호기심에서 읽나요? –

+0

iPhone 3 개발 시작 (http://www.amazon.com/Beginning-iPhone-Development-Exploring-SDK/dp/1430224592/ref=sr_1_1?ie=UTF8&s=books&qid=1255312956&sr=8-1). 꽤 좋지만, 실제로 읽은 모든 장에서 오류와 누락이 아주 분명합니다. 너무 진지한 것은 아니지만 제 2 판을 위해 얼마나 많은 노력을 기울 였는지 질문 할만큼 충분합니다. – Kenny

답변

9

에 브러시 할 수 있습니다.

이름에 alloc, copy 또는 new가있는 메소드는 객체에 대한 메모리를 할당하고 해당 객체의 소유권을 호출자에게 제공하며 호출자는 해당 메모리를 해제해야합니다.

viewDidLoad 메서드에서 개체의 소유권을 제공하는 메서드를 호출합니다. 그것을 공개하는 것은 귀하의 방법입니다. 그러나 그렇게하기 전에 무엇인가하고 싶습니다. 결국, 할당 한 이유입니다. 방금 출시하지 않고 유용하게 사용할 수 있습니다.

무엇을하고 싶은지에 관계없이 해제해야합니다 (또는 자동 다시 실행 *). 이 경우 객체의 사용은 self.breadTypes에 전달하는 것입니다. self.breadTypes는 메소드처럼 보일 수는 없지만 setter입니다. 그걸 빵에 넘겨 .Array. 그것은 그것이 필요한 것입니다. 나중에 사용하기 위해 보관할 수도 있고 일부 정보를 복사하거나 전체 내용을 복사 할 수도 있습니다. 귀하의 viewDidLoad 정말 상관 없어. 그것은 self.breadTypes가 필요한 것을 수행한다고 가정하고 반환 할 때 breadArray로 무엇을하는지 상관하지 않습니다.

그리고 그걸로 무엇을 할 수 있습니까? 당신이 소유하고있는 것, 즉 release (또는 autorelease * it)와 관련이 있습니다.

그래서 temp 변수 breadArray를 사용해야합니다. 객체가 self.breadTypes 이전에 출시 얻을 것이기 때문에 당신은 확실히 그것을 할 수 있습니다, 같은 줄에 ALLOC의 결과를 공개 할 수 없습니다

self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil] release]; 
따라서

당신이 임시 변수에 할당 강제로 그것을 통과 self.breadTypes로 이동 한 다음 breadArray에 저장된 객체를 놓습니다.

지금, 당신은 당신이 임시 변수를 사용하지 않습니다 그래서이 방법을 시도 할 수 있습니다 :

- (void)viewDidLoad { 
    self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @..., nil]; 
    [self.breadTypes release]; 
} 

을하지만 (A와 self.breadTypes을 또 다른 메소드를 호출하기 때문에 그것은 매우 효율적이지 않다 getter)를 사용하면 방금 값을 임시 변수에 저장 한 경우에는 필요하지 않습니다. 응답자 말했듯이

* 이제, 당신은 다른 버전의 오토 릴리즈 사용할 수 있습니다

- (void)viewDidLoad { 
    self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil] 
         autorelease]; 
} 

애플은 우리가 오토 릴리즈 대 릴리스를 사용할지 여부에 대해 두 번 생각하는 우리를 촉구한다. Autorelease가 모든 상황에 가장 적합한 선택이 아닐 수도 있습니다. 나는 개인적으로 가능한 한 빨리 나 자신을 정화하고 autorelease를 불필요하게 사용하지 않는다. 자동 반복 실행 된 객체는 실행 루프가 끝날 때 해제됩니다 (예 : viewDidLoad가 반환 된 직후). MacOS X 코코아와 약간 다른 autorelease (그리고 아이폰의 메모리 관리)에 대해 좀 더 자세히 읽어보아야한다.

동의어 : 객체가 retain 인 경우 소유권이 있다고 가정하고 작업을 완료 한 후에는 동일한 책임을 다시 수행합니다. release

+0

시간을내어 작성해 주셔서 감사합니다. 그것은 매우 도움이되었습니다. – Kenny

3

예. 이러한 메소드는 변수를 할당하여 릴리스해야합니다. 속성에 retain 속성이 있다는 사실은 이라고 말하면 컴파일러가 현재 breadType 멤버를 적절하게 해제하고 새 멤버를 유지하는 setBreadTypes을 실제로 생성하고 있음을 의미합니다. 따라서 함수는 변수 alloc을 유지하지 않아야합니다.

당신은, 그러나 작성할 수

- (void)viewDidLoad { 
    self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", 
           @"Whole Wheat", @"Rye", @"Sourdough", 
           @"Seven Grain", nil] 
         autorelease]; 
} 

당신은 저를 시도하고 다른 방법으로 그것을 설명하게 Cocoa Memory Management

+0

대단한 답변을 보내 주셔서 감사합니다. 제공된 링크를 읽습니다. – Kenny

관련 문제