2010-12-07 5 views
0

내가 가진 :아이폰 오브젝티브 C 자체의 문제

- (void)viewDidLoad { 
    NSArray *array = [[NSArray alloc]initWithObjects:@"Pictures",@"Video",@"Text",@"Map",nil]; 
    self.selectionList = array; 
    [array release]; 

    [super viewDidLoad]; 
} 
... 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    NSUInteger row = [indexPath row]; 
    cell.textLabel.text = [selectionList objectAtIndex:row]; 

    return cell; 
} 

내 질문은 이것이다, 이유있는 viewDidLoad 섹션에, 그것은 self.selectionList뿐 아니라 selectionList 할 필요합니까? 내 말은, 요점은 selectionList 배열에 방금 작성한 배열의 내용을 전달하는 것입니다. 그래서 왜 자기입니까?

+0

속성 및 Objective-C 메모리 관리에 대한 설명 – nduplessis

+1

사이드 노트 : 'viewDidLoad'는 먼저 부모 호출 (첫 번째 줄)을 가져야합니다. –

+0

@ 케빈 : 차이를 만들어서는 안됩니다. 애플의 문서에서는 종종 전혀 그렇지 않습니다. – Eiko

답변

1

'self'를 사용할 때마다 setter 및 getter 속성을 사용합니다. 즉, 보유중인 속성을 만들면 release (설정자가 retain을 호출하므로)을 허용합니다. 당신이 세터를 사용하지 않은 경우, 당신은 또한 다음과 같이 위의 쓸 수 있었다 (나는 그것이 재산을 유지입니다 있으리라 믿고있어) (하지만 난 그것을 권하고 싶지 않다) :이 경우

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    selectionList = [[NSArray alloc]initWithObjects:@"Pictures",@"Video",@"Text",@"Map",nil]; 
} 

- (void)dealloc 
{ 
    [sectionList release]; 
    [super dealloc]; 
} 
+2

배열이 이미 초기화 된 경우, 즉 -init – Eiko

+0

배열이 누출됩니다. 그래, 배열이 초기화되지 않았다고 가정했지만 사실입니다. –

+1

viewDidLoad는 두 번 이상 호출 될 수 있습니다 (예 : 메모리 경고의 경우). 따라서 수동으로 수행하는 경우 새 목록을 지정하기 전에 [selectionList release]를 수행해야합니다. – Eiko

0

여기서 차이점은 메모리 관리가 작동하는 방식입니다. @property selectionList가 retain으로 정의되면 self.selectionList = something;을 호출하면 [selectionList retain]가 암시 적으로 호출됩니다.

이 특정 예제에서 단순히 selectionList = something;을 수행하면 개체가 릴리스되므로 줄을 아래쪽으로 충돌 할 가능성이 높습니다.

0

, 이것은 setter 메소드를 사용하기 때문에 self.selectionList 여야합니다 (헤더에 retain 속성이있는 속성을 사용한 다음 구현에서 selectionList를 합성했다고 가정합니다). 그것은 실제로하는 것과 똑같습니다 ...

[self setSelectionList:array]; 

... 그게 합리적이라면.

그렇지 않은 경우 배열을 클래스 인스턴스 변수에 할당하기 만하면 배열이 올바르게 관리되었는지 확인하기 위해 유지 및 후속 릴리스를 수행해야합니다.

+0

왜 downvote? (나는 무엇을 놓쳤는가?) –

+0

그것은 내가 아니었지만,이 대답으로 볼 수있는 유일한 문제는 그가'alloc' 된 기억을 가지고 있기 때문에, 실제로 자동 보유가되지 않았기 때문에 실제로 보유 할 필요가 없다는 것입니다. , 그냥 후속 릴리스. 그가 여기에 세터를 사용했다면, 기억을 할당하는 것 외에도 그는 두 배의 유지력을 가졌을 것입니다. 올바른 패턴은 setter를 사용하여 assign을 할당 한 다음 원본을 해제하는 것입니다. –

+0

@Sam - 아, 그래. 헤드 업에 감사드립니다. 다음 번에 더 자세히 설명하려고 노력할 것입니다. :-) –

1

self.selectionList는 인스턴스 변수에 직접 액세스하는 대신 속성 (-> setter 메서드)을 사용하기 때문에. 이렇게하면 직접적인 ivar 접근으로는 불가능했던 서브 클래스에서이 변수 액세스를 덮어 쓸 수 있습니다. 속성을 사용하는 것이 일반적으로 더 깨끗한 접근법 (데이터 캡슐화/정보 숨김)입니다.

다른 주석에서 언급 한 바와 같이 : 속성이 없으면 모든 지점에서 메모리 관리에 관심을 가져야합니다. 이 경우 릴리스를 삭제해야한다는 것을 의미합니다.

1

ratain 또는 copy ing 속성에 대해 도트 구문을 사용하면 다음과 같은 세 가지 효과가 있습니다. 선언에 따라 배열을 할당하거나 복사하고 보관 메시지가 유지되도록합니다 살아 있고, 또한 중요합니다 - 누설되지 않도록 이전 배열을 release으로 만드십시오.

도트 구문을 사용하지 않으려면이 모든 단계를 수동으로 수행해야합니다.

+0

그래서, 당신이 말하는 것은 저의 [배열 해제]입니다; 여기 전화는 불필요한가요? 도트 구문이 나를 위해 그것을하고있다? – startuprob

+0

아니요. 코드는 그대로 유지됩니다. 릴리즈는 alloc/init의 균형을 유지합니다. 메모리 관리 안내서를 읽으십시오 - 충분히 권할 수는 없습니다. 한 번 이상 읽을 가치가 있습니다. :-) – Eiko

관련 문제