2

나는 항상 혼란 스럽습니다. 누군가 나를 위해 그것을 설명해 주시겠습니까?보기 및 다른 객체 누설

보기 컨트롤러 클래스에서 나는 예를 들어 스크롤보기를 가지고 있으며 여러보기를 추가하려고합니다. 그래서 뷰 ​​컨트롤러 내에서 뷰를 생성하고 호출자에게 반환하는 도우미 메서드를 만듭니다. 그러면 호출자는이 새로운 뷰를 스크롤 뷰에 추가합니다.

-(UIView *)getView { 

    UIView *v = [[UIView alloc] init]; 

    // do all the guff I need to configure the view 

    return v; 
} 

문제는 어디 또는 때입니다 :

그래서 여기에 내가 여기에보기를 얻을 addSubView:

[scrollView addSubView:[self getView]]; 

에 직접 통과하는 메소드를 호출하면 뷰를 작성하는 방법입니다 v가 출시 되나요? getView에서 생성 될 때 autorelease으로 할당해야합니까, 아니면 addSubView:을 호출 한 후에 해제해야합니까? 감사.

그의 이유는
return [v autorelease]; 

답변

2

, 당신은 getView-autorelease 메시지의 반환 값을 전송해야한다 그것에게 -retain 메시지를 보내 건네 볼의 소유권을 획득 잘못되었거나 적어도 불분명 함 (그리고 나는 시도했지만 코멘트로 짜내는데 실패했다).

getSubview:에서 개체를 만들었습니다. 이제 당신은 소유자 *입니다. 메서드가 끝나면 개체를 해제하거나 소유권을 포기해야합니다. 그렇지 않으면 유출됩니다. 메서드에서 객체를 반환한다는 사실은이 규칙과 아무런 차이가 없습니다. 이 경우

, 당신은 객체와 뭔가을 할 수 있도록이 방법이라는 코드를 원하기 때문에, 당신은 autorelease가 내 소유권을 포기 "말을 사용하지만, 실제로는이 개체를 제거하지 않습니다 호출 코드가 주장을하기를 원하는지를 볼 기회가있을 때까지 ". 다른 쪽 끝에서 일어나는 일 (보관, 복사, 즉각적인 배포, 기타)은 getSubview:의 코드와 관련이 없습니다. 모든 방법은 소유권이있는 메모리에 대해 걱정해야합니다. 그렇지 않으면 호출 코드가 메모리와 관련된 특정 작업을 수행한다는 사실에 의존하여 버그가 발생합니다.

약간 더 기술적 인 측면에서 v은 메서드의 끝 부분에서 범위를 벗어나므로 v이 가리키는 개체를 릴리스하거나 자동으로 변환해야합니다. 이름이 범위를 벗어나면 그 이름을 더 이상 객체를 참조하는 데 사용하지 않아야하며 그 이름이 객체에 대한 유일한 참조 인 경우 사용자는 유출 한 것입니다. retain 그것이 파트 소유자가이야 다른 객체 -


*이 객체가 여러 소유자를 가질 수 있습니다.

+0

감사합니다. – user7865437

+1

한 번에 하나의 코드 블록 만 생각하면 이러한 메모리 관리 질문이 훨씬 쉬워집니다. 당신의 도우미 방법을 고려하십시오 : 당신은 객체를 생성해야합니다. 퇴근 후에 무슨 일이 일어나는지는 당신의 방법에 아무런 문제가되지 않습니다. – kubi

+1

도우미 메서드를 호출 할 때 : 메서드 서명 ('getView')은 규칙에 따라 자동 렌더링 된 개체를 반환합니다.소유권을 가져 오려면이 개체를 유지하고 그렇지 않으면 아무 것도하지 않습니다. – kubi

0

야곱의 결론은 정확하지만 : -[UIView addSubview:] 이후